赞
踩
因项目需求,需要从SpringBoot2.6升级到3.2,同时JDK需要从jdk8升级到jdk17.SpringBoot和JDK都跨了几个大版本,部分配置和接口都有变动,相关代码需要调整的部分比较多。根据Spring官方建议,决定把SpringBoot分三个阶段进行,第一阶段2.6->2.7,同时JDK直接升级到17,第二阶段2.7->3.0,第三阶段3.0-3.2.这样每一阶段侧重点不,分散升级压力,每阶段升级成功后都需要对当前项目代码进行测试,尽量保证升级不变动业务代码。
第一阶段,SpringBoot2.6->2.7,JDK8->17
项目主要分为两部分,基础组件包和业务代码。基础组件包主要是项目框架的依赖封装以及通用组件封装,大部分项目都引用基础组件包。业务代码是每个项目具体业务的实现。理论上升级只影响基础组件包,业务代码受影响比较小。
1.SpringBoot2.6->2.7
官方建议:Spring Boot 2.7 Release Notes · spring-projects/spring-boot Wiki · GitHub
根据官方建议和项目实际情况,SpringBoot升级到2.7.18版本,升级主要变动的部分是Security部分,WebSecurityConfigurerAdapter已经弃用,需要迁移到SecurityFilterChain。迁移时需要注意:原configure方法使用SecurityFilterChain替换。
注:如果只是升级到SpringBoot2.7.18,WebSecurityConfigurerAdapter只是标记弃程序还是可以正常运行的,但SpringBoot3.0之后会删除,所以这里还是需要修改。
SpringBoot 2.6安全配置
- @Configuration
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
-
-
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- // @formatter:off
- http.authorizeRequests((authz) -> authz.anyRequest().authenticated())
- .csrf((csrf) -> csrf.ignoringAntMatchers("/token"))
- .httpBasic(Customizer.withDefaults())
- .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
- .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
- .exceptionHandling((exceptions) -> exceptions
- .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
- .accessDeniedHandler(new BearerTokenAccessDeniedHandler())
- );
- // @formatter:on
- }
-
- @Bean
- UserDetailsService users() {
- // @formatter:off
- return new InMemoryUserDetailsManager(
- User.withUsername("user")
- .password("{noop}password")
- .authorities("app")
- .build()
- );
- // @formatter:on
- }
-
- }

SpringBoot 2.7安全配置
- @Configuration
- public class SecurityConfig {
- @Bean
- public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
- // @formatter:off
- http
- .authorizeHttpRequests((authorize) -> authorize
- .anyRequest().authenticated()
- )
- .csrf((csrf) -> csrf.ignoringAntMatchers("/token"))
- .httpBasic(Customizer.withDefaults())
- .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
- .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
- .exceptionHandling((exceptions) -> exceptions
- .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
- .accessDeniedHandler(new BearerTokenAccessDeniedHandler())
- );
- // @formatter:on
- return http.build();
- }
-
- @Bean
- UserDetailsService users() {
- // @formatter:off
- return new InMemoryUserDetailsManager(
- User.withUsername("user")
- .password("{noop}password")
- .authorities("app")
- .build()
- );
- // @formatter:on
- }
- }

2.JDK 8->17
可以用jdeps --jdk-internals --multi-release 17 --class-path . 做项目依赖分析。
JDK 11中已经移除了移除了 Java EE and CORBA 的模块,如果代码中用到了 javax.annotation.*
下的包,需要引入 javax 的包:
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>javax.annotation-api</artifactId>
- <version>1.3.5</version>
- </dependency>
如果项目中使用了lombok,需要升级到1.18以后的版本:
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.18.30</version>
- </dependency>
Java Bean复制问题,原来Bean复制使用org.springframework.cglib.beans.BeanCopier来处理,升级JDK 17后遇到类反射问题,因为原来Bean包装成一个工具类,为了减少影响,使用ModelMapper替换。后面Bean复制推荐使用MapStruct方式。
旧的Bean复制方式
-
- public static void copy(Object source, Object target, Converter converter) {
- BeanCopier beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
- beanCopier.copy(source, target, converter);
- }
新的Bean复制方式
- <dependency>
- <groupId>org.modelmapper</groupId>
- <artifactId>modelmapper</artifactId>
- <version>3.2.0</version>
- </dependency>
-
- public static Object copy(Object source, Object target, Converter converter) {
- ModelMapper modelMapper = new ModelMapper();
- Type type = TypeToken.of(target.getClass()).getType();
- return modelMapper.map(source, type);
- }
第二阶段,SpringBoot2.7->3.0
官方建议:Spring Boot 3.0 Migration Guide · spring-projects/spring-boot Wiki · GitHub
1.首先需要做升级前检查,把Spring Security 从5.7升级到5.8,把用到@Deprecated的类或方法替换成官方建议的类或方法。
2.Jakarta EE升级
SpringBoot3.0使用Jakarta EE10,原来javax的包变成了jakarta,官方给出了3种升级方式,建议使用 IntelliJ IDEA工具升级。工具位置:Refactor->Migrate Packages and Classes->Java EE to Jakarta EE.
3.自动配置文件修改
原来使用starters方式的模块会将启用自动配置类以org.springframework.boot.autoconfigure.EnableAutoConfiguration为key写到spring.factories中,SpringBoot2.7版本新增了META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,需要将自动配置类写到该文件中,如果登记多个配置类,文件中每行放一个。SpringBoot3.0弃用了spring.factories中的org.springframework.boot.autoconfigure.EnableAutoConfiguration这个key,用imports文件替代。
4.swagger升级
swagger需要升级到swagger3.0,引入以下依赖
- <dependency>
- <groupId>org.springdoc</groupId>
- <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
- <version>2.5.0</version>
- </dependency>
升级到3.0后swagger注解需要修改,下面是2.0和3.0注解的对应关系
@Api → @Tag @ApiIgnore → @Parameter(hidden = true) or @Operation(hidden = true) or @Hidden @ApiImplicitParam → @Parameter @ApiImplicitParams → @Parameters @ApiModel → @Schema @ApiModelProperty(hidden = true) → @Schema(accessMode = READ_ONLY) @ApiModelProperty → @Schema @ApiOperation(value = "foo", notes = "bar") → @Operation(summary = "foo", description = "bar") @ApiParam → @Parameter @ApiResponse(code = 404, message = "foo") → @ApiResponse(responseCode = "404", description = "foo")
5.URL匹配方式
Spring Framework 6.0之后不支持末尾斜杠的方式,默认情况下末尾斜杠的URL会报404错误。可以通过配置打开此设置:
- @Configuration
- public class WebConfiguration implements WebMvcConfigurer {
-
- @Override
- public void configurePathMatch(PathMatchConfigurer configurer) {
- configurer.setUseTrailingSlashMatch(true);
- }
-
- }
URL匹配模式发生变化,不支持**的方式,需要替换为*,如下
/**/*.css -> /*/*.css
6.Jetty
Jetty目前还不支持Servlet 6.0,如果在SpringBoot 3.0使用Jetty需要降级到Servlet 5.0.
7.Http Client
对Apache HttpClient的支持在Spring Framework 6.0中被移除,被org.apache.httpcomponents.client5:httpclient5取代
8.数据访问
Cassandra属性修改:spring.data.cassandra.
变为 spring.cassandra.
Redis属性修改:spring.redis.
变为 spring.data.redis.
MySQL驱动类修改:mysql:mysql-connector-java
变为 com.mysql:mysql-connector-j
第三阶段,SpringBoot3.0->3.2
HttpClient4相关依赖被删除,推荐使用HttpClient5.
总结
升级难点主要有几个方面,JDK17升级,javax的包变成了jakarta这个需要修改的比较多,如果引入第三方包需要每个都去找支持JDK17的版本,如果没有支持版本可能需要自己重新编译一个JDK17版本;SpringBoot升级尽量不要一次升级到3.2版本,否则需要修改的内容过多导致混乱;第三方包有可能影响较大,如果有不支持JDK17的包需要替换或重新编译。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。