Springboot2.6升级到3.2

因项目需求,需要从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的包需要替换或重新编译。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值