专业的编程技术博客社区

网站首页 > 博客文章 正文

Springboot2.6升级到3.2

baijin 2024-12-03 10:08:03 博客文章 7 ℃ 0 评论

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

?

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表