前言
最近把项目升级到了Spring Boot 3.x,顺便记录一下升级过程中遇到的一些新特性和变化。其实升级还算顺利,就是有些依赖和配置调整了一下。
JDK版本要求
首先最明显的变化就是JDK版本要求了,Spring Boot 3.x最低要求JDK 17,基础也升级到了Jakarta EE 9
所以如果你的项目还在用JDK 8或者JDK 11,得先升级JDK版本
我用的JDK 17,感觉还不错,新版本的一些语法糖确实好用
依赖包变化
javax到jakarta的迁移
这个改动挺大的,所有的javax.*包都改成了jakarta.*
比如之前的:
1 2 3
| import javax.servlet.http.HttpServletRequest; import javax.persistence.Entity; import javax.validation.constraints.NotNull;
|
现在要改成:
1 2 3
| import jakarta.servlet.http.HttpServletRequest; import jakarta.persistence.Entity; import jakarta.validation.constraints.NotNull;
|
如果项目里用了大量的javax包,这个迁移工作量还挺大的。IDEA有自动替换功能,但是有些地方还是得手动改
我这边主要涉及的是Spring Security和Validation相关的注解
Spring Security 6的变化
Spring Security也跟着升级到了6.x,配置方式有一些调整
之前常用的WebSecurityConfigurerAdapter已经被彻底移除了
现在推荐使用基于组件的配置方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| @Configuration @EnableWebSecurity public class SecurityConfig {
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.disable()) .authorizeHttpRequests(auth -> auth .requestMatchers("/user/login").anonymous() .anyRequest().authenticated() ) .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) .exceptionHandling(exception -> exception .authenticationEntryPoint(authenticationEntryPoint) .accessDeniedHandler(accessDeniedHandler) ) .cors(cors -> cors.configure(http));
return http.build(); }
@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
@Bean public AuthenticationManager authenticationManager( AuthenticationConfiguration authConfig) throws Exception { return authConfig.getAuthenticationManager(); } }
|
这种新的配置方式用的是Lambda DSL,写起来确实比之前简洁一些,但是刚开始看还有点不习惯
可观测性改进
Spring Boot 3.x在可观测性方面做了不少改进,整合了Micrometer Tracing
之前用Spring Cloud Sleuth做链路追踪,现在可以直接用Micrometer Tracing了
添加依赖:
1 2 3 4 5 6 7 8
| <dependency> <groupId io.micrometer</groupId> <artifactId>micrometer-tracing-bridge-brave</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-observation-registry</artifactId> </dependency>
|
配置文件里添加:
1 2 3 4 5 6 7
| management: tracing: sampling: probability: 1.0 zipkin: tracing: endpoint: http://localhost:9411/api/v2/spans
|
这样就能自动追踪请求链路了,挺方便的
AOT编译和GraalVM
Spring Boot 3.x支持AOT(Ahead-of-Time)编译和GraalVM原生镜像
这个功能可以让应用启动更快,内存占用更少
不过我暂时还没在生产环境用,毕竟GraalVM的兼容性还有待验证,有些反射和动态代理的场景可能会出问题
如果要尝试原生镜像,可以添加依赖:
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aot</artifactId> </dependency>
|
然后用命令构建:
1
| mvn -Pnative native:compile
|
构建出来的可执行文件启动确实快,从我测试来看,启动时间从2秒左右降到了不到100ms
配置属性的变化
有些配置属性的名称也变了
比如之前配置DataSource:
1 2 3 4 5 6
| spring: datasource: url: jdbc:mysql://localhost:3306/test username: root password: password driver-class-name: com.mysql.cj.jdbc.Driver
|
现在url改成了jdbc-url:
1 2 3 4 5 6
| spring: datasource: jdbc-url: jdbc:mysql://localhost:3306/test username: root password: password driver-class-name: com.mysql.cj.jdbc.Driver
|
不过旧的url属性还能用,只是会有个警告提示
其他小改动
Actuator路径变化
有些actuator的端点路径变了:
/actuator/httptrace 改成了 /actuator/httpexchanges
/actuator/caches 的响应格式也有调整
LocalDate支持
@DateTimeFormat注解现在支持java.time类型了,不用再自己写转换器
1 2 3 4 5 6 7 8 9
| @RestController public class UserController {
@GetMapping("/users") public List<User> getUsers( @RequestParam @DateTimeFormat(iso = ISO.DATE) LocalDate date) { } }
|
总结
总的来说,Spring Boot 3.x的升级还算平滑,主要就是:
- JDK版本要求提升到了17
- javax包名迁移到jakarta
- Spring Security配置方式改变
- 可观测性增强
- 支持GraalVM
建议升级前先做充分测试,尤其是涉及到一些底层框架或者第三方依赖的部分
我这次升级还算顺利,就是花了点时间改包名和Security配置。升级完之后,感觉性能和可维护性都有提升,还是值得的
暂时就先记录这么多,后面如果遇到其他坑再补充