SpringBoot 项目开发小技巧

小七学习网,助您升职加薪,遇问题可联系:客服微信【1601371900】 备注:来自网站

SpringBoot 是项目开发中的地位举足轻重,虽然说 SpringBoot 采用了约定大于配置,但是在实际的应用中还是需要对一些配置进行修改,以适应项目的实际需求。

SpringBoot 是项目开发中的地位举足轻重,虽然说 SpringBoot 采用了约定大于配置,但是在实际的应用中还是需要对一些配置进行修改,以适应项目的实际需求,在本文中,将会从实用的角度,介绍一些常用的功能配置,主要涉及一下内容:

  • SpringBoot 配置文件的 configuration
  • SpringBoot 的异步任务如何配置。
  • 3 项目定时任务的配置
  • Event 事件处理
  • ApplicationContextAopContext 和 RequestContextHolder 等的使用方法。
  • springmvc 参数获取的那些方法。


1 前言

目前在项目开发中,开发框架大多都是使用的都是 springboot,在实际的开发中,大多使用的是默认配置,这对于快速开发与交付来说已经足够,但是在特定的业务场景下可能就不满足需求了,在文中会讲解一下 springboot 开发中常用的一些技巧,以期在工作中能带来帮助。

2 项目配置文件

在日常的开发任务中,通常会在 application.yml 或者 application.properties 中配置业务信息,如下图所示:

app:  info:    name : 小明12    age: 12    birthday: 2022-01-22    weight: 23.4    height: 32    money: 12.0    user_pets:      - dog      - cat    user_ext:      learn: maths      hobby: runing

大家都会想到使用 @ConfigurationProperties 来解析配置文件中的内容,在实际的操作中也是使用这种方式比较方便一点。记得之前在 spring 项目中采用的是@Value 的方式来注入配置信息,需要写的内容是相当多的。而在 springboot 中,可以实现配置与 java bean的映射,还会完成下划线到驼峰格式的转化,相当的 nice。在@ConfigurationProperties中添加 prefix 参数来指定前缀可以使得配置与 java bean 映射无缝衔接。这里列举了几种常用的类型,而且添加了 list 以及 map 的结构,除了 date 类型的比较特殊,需要进行格式的转换,其他的类型基本不需要。 app config 到这里,大多数的工作就结束了,但是会有一个不爽的地方,如下图所示,显示是不能解析这个配置,但是不影响项目的运行,只是打开文件的时候不太美观。这是因为 springboot 不会识别自定义的配置文件,少了一些 metadata.json 解析文件,如何解决这个问题呢?只需要在 pom.xml 中再引入一个依赖即可解决这个问题:

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-configuration-processor</artifactId>    <optional>true</optional></dependency>

引入依赖后,再次编译项目,会在 target 中 META-INF 生成一个 metadata.json 文件,如下图所示,就是将需要配置的信息进行了设置。

meata 信息

完成以上的配置后,再次编辑配置信息时就会给予提示信息,而且不会有黄色底纹不能解析的情况。 提示信息

3 异步任务

在项目中使用异步任务,是经常用到的事项,通常是为减少请求的等待时间,将业务处理进行异步后台处理,可以改善用户的体验,增加系统的吞吐量。

在 springboot 中开启异步任务,也是十分的简单,只需要两步操作:

  • 1 开启 @EnableAsync 注解。
  • 2 在需要异步处理的方法上添加 @Async

需要说明的是异步执行的方法可以有返回值,但是必须是 Future,这里和多线程 submit 的方式提交任务,获取处理结果的方式。

到此为止,异步任务的配置和使用就结束了。异步任务使用的也是多线程线程池技术,默认情况下采用的是 SimpleAsyncTaskExecutor 来实现,但是自己的命运怎么能交到他人手上呢,总觉得不太踏实,异步任务怎么才能使用自定义的线程池去实现呢,这是一个好问题,答案也是有的,那就是 AsyncConfigurer。这是一个接口,需要实现 getAsyncExecutor 方法来获取一个线程池,如果需要异常信息的抓取,则在实现一个方法 getAsyncUncaughtExceptionHandler 即可。具体的代码如下所示: 异步任务线程池配置

异步任务执行结果如下,可以说明异步任务的线程池配置已经生效: 在这里插入图片描述

4 定时任务配置

定时任务在项目开发中可以说是很常用的配置,作为业务功能的补偿而存在,有这举足轻重的地位,对于定时任务的使用,可以分为固定时间和 crontab 表达式,在实现的工具上,有 spring 自带的 @Schedule,在单体项目中应用广泛,不需要借助其它的平台和额外的配置,对于简单的任务来说已经足够,但是对于分布式系统来说,就有点儿力不从心了,这时就诞生了 quartz、 elastic-job 和 xxl-job 等,其中 xxl-job 尤为出色。在这里,只介绍一下 @Schedule 的使用:

  • 1 全局开启 @EnableScheduling 注解。
  • 2 在需要执行的任务上添加 @Schedule 注解,并指定执行方法,是固定执行还是采用 cron 表达式。

在实际的项目开发中,crontab 表达式应用还是很广泛的,这里给一下 cron 表达式生成地址,以供参考:

https://www.bejson.com/othertools/cron

定时任务配置

和异步任务执行一样,定时任务的执行也是有自己的异步任务线程池,这里需要实现的接口为 SchedulingConfigurer ,实现其 configureTasks 方法即可: 异步任务线程池配置 在一切配置文件做好后,运行后可以看出定时任务的线程池配置已经生效: 定时任务执行结果

5 spring 事件

spring 事件可能在实际的应用中场景比较少,但实在确实是一个很好用的功能,事件类似于 mq 消息发送,在轻量级的应用场景中还是值得一用,但是 event 属于同步执行,主线程和事件处理线程是同一线程,只不过将返回结果进行了返回。 在使用事件时,需要先创建一个事件实体,用来承载信息: 声明事件 既然是异步处理,就需要创建一件监听器来监听事件进行触发业务操作: 事件监听器 在处理事件时,我们依旧采用独立的线程来进行任务处理,异步线程如下所示: 事件处理 在配置和业务操作处理完毕后,需要使用 ApplicationEventPublisher 来发布事件,事件的接受和处理结果如下图所示: 事件执行

6 上下文信息

在实际的业务中,获取 Spring 容器中的上下文信息是十分常见的操作,主要是用于获取 Bean 来处理业务,在策略模式中该操作十分常见,关于上下文的对象的获取,如下图所示:

ApplicationContext 的获取方式如下图所示,在使用时,仅调用一下 ApplicationContextHolder.get() 方法即可。 spring 上下文获取

在 spring 事务操作中,在同一个类的内部事务方法调用另外一个事务方法会导致事务失效,这个是动态代理的问题,如何避免这样的情况呢,这里就使用到了 AopContext 来获取当前的代理对象进行转换,即可进行处理,保证事务不会失效,不过这样的使用方法并不常见。这样的配置生效,需要另外一个配置项 @EnableAspectJAutoProxy(exposeProxy = true),默认 exposeProxy= false,因为需要获取代理对象,这里需要将代理对象进行暴露。 Aop 上下文获取 获取 http 的上下文,可以获取 HttpRequest 的信息,这个 RequestContextHolder 存储的就是当前请求的 http 访问信息,具体操作如下所示: http 上下文获取

类似于上下文的获取还有很多,比如在 Dubbo 框架中,就可以使用 RpcContext 来获取信息,可以说是非常的 nice。期待发掘更多的获取上下文信息的方式和方法。其实上下文信息,无非就是 Threadlocal 和 动态代理两种实现路径,这里只是涉及实际应用,原理的话后续会出专门文章进行分享,一入开发深似海呀。

7 spring mvc 参数获取

对于 spring mvc 参数的获取,可以说大家都是得心应手的,但是还是需要在这里总结一下的,除了常见的操作比如 @RequestBoy 和 @RequestParam 之外,还有类似于如下操作: 请求参数操作 这里有 @PathVariable 和 @RequestHeader ,前者是从请求路径中获取参数,后者则是从请求头中获取参数,这里需要说明的是从请求路径中获取参数也可以指定正则的方式,但是这种方式并不可取,因为参数校验一般由专门的 validate 来进行处理,这样职责更分明一些。需要说明的是,.+ 的方式是为了获取参数中带有 . 的情况,比如 http://localhost:9091/api/head/param/1234.doc1234.doc就是一个参数,如果没有正则表达式的话,会漏掉 .doc 的部分。在大多数的应用场景下,接口的命名不会如此来处理,大部分的场景都是使用 POST 方式来传递参数,如果是 GET 请求,也会将固定参数的名称,只有在需要获取请求头的时候可能会用到 @RequestHeader 来处理。为什么不推荐 @PathVariable 呢,这样会导致在做接口统计时不好处理, 同样一个接口,因为参数名称千变万化,还需要进一步处理映射关系,使得统计工作添加额外的复杂度。

parms params 是一个神奇的参数,在业务迭代开发中,如果保持接口的兼容,而且还想实现接口的新功能,可以在参数中添加固定的参数来进行区分。例如:

# 不添加 params 参数http://localhost:9890/api/config 访问的是 config 方法# 添加 params = \"constant\" 可访问 config1 方法http://localhost:9890/api/config?constant=xxx# 添加 params = \"constant=123\" 可访问 config1 方法http://localhost:9890/api/config?constant=123

总结一下就是:

  • params:请求中必须包含某些参数值方法才处理。
  • headers:和 params 类似,请求头包含某些固定参数方法才处理。

8 总结

在本文中,介绍了配置文件相关的内容,异步任务、定时任务和事件都是围绕着线程池来展开,最后介绍了获取上下文信息的常用类型,以及参数获取的一些内容,其实在 RequestContextHolder 的情况下,参数获取将会获取的非常简单。在本文中介绍了简单的应用,后续会持续更新,介绍其实现原理,毕竟会用只是第一步,了解原理才是核心竞争力,再次基础之上就可以进行创新和创造。案例中涉及的代码均已上传至 github,欢迎大家关注。项目地址 springboot-templet-start/springboot-config

小七学习网,助您升职加薪,遇问题可联系:客服微信【1601371900】 备注:来自网站

免责声明: 1、本站信息来自网络,版权争议与本站无关 2、本站所有主题由该帖子作者发表,该帖子作者与本站享有帖子相关版权 3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和本站的同意 4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责 5、用户所发布的一切软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。 6、您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 7、请支持正版软件、得到更好的正版服务。 8、如有侵权请立即告知本站(邮箱:1099252741@qq.com,备用微信:1099252741),本站将及时予与删除 9、本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章和视频仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。