简单记录下Spring boot 3.1的升级过程

Spring Boot在2023年的5月18号发布了3.1版本,手里有些项目版本是2.X,借这个机会把项目升级到最新版本+更新JDK 20

在这里简单随便记录一下踩坑的地方,在文章的末尾放上了官方的migration向导,你可以根据此参考升级你的项目。

 

通过Spring Initializr获取最新的版本,拷贝至项目里。 

引入migrator依赖

项目引入migrator依赖会析应用程序的环境和打印诊断,会在启动时打印出某个属性过期了需要更新修改替换等。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-properties-migrator</artifactId>
    <scope>runtime</scope>
</dependency>
或者,使用Gradle:

runtime("org.springframework.boot:spring-boot-properties-migrator")

 

 

替换avax包名

2009 年,Oracle宣布收购 SUN,Java 相关技术自然归 Oracle 所有,在 2017 年,Oracle 宣布开源 Java EE 并将项目移交给 Eclipse 基金会。
但不能再使用 Java EE这个 名称,Eclipse 基金会接受了这个要求并且改名为 Jakarta EE

javax的包名都需要替换成jakarta,可以用IDE的批量查找替换功能直接把javax替换成jakarta,但为了替换更精确,我还是把名字写长了一点。

import  javax.validation  => import  jakarta.validation

import javax.servlet. =>  import jakarta.servlet.

import javax.mail.  => import jakarta.mail.

import javax.inject. = > import jakarta.inject

 

迁移spring security至6.1

本次spring boot 3.1中将spring security版本升级到了6.1其中很多东西发生了变化,比如常见的配置WebSecurityConfigurerAdapter直接被删除。

如果你有类似与这种配置,都需要替换成Bean注入的形式:

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {   httpSecurity   .csrf().disable()   //其他配置... }

将其替换为:

@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) {
return 
 httpSecurity.csrf(c->c.disable());
   //其他配置
    http.build();
}

还有一个细节是,这些配置现在都变成函数式了

通过查看方法参数声明得知,

HttpSecurity csrf(Customizer<CsrfConfigurer<HttpSecurity>> csrfCustomizer)....
@FunctionalInterface
public interface Customizer<T> {
   void customize(T t);

   static <T> Customizer<T> withDefaults() {
      return (t) -> {
      };
   }
}

我们需要把配置进行一下修改:

将httpSecurity.csrf()  ;
变为: httpSecurity.csrf(c->c.disable()) ;
或者用Method Reference语法简写为: http.csrf(AbstractHttpConfigurer::disable);

其他列如
http.authorizeHttpRequests也是如此

spring seuciry的关于自动保存SecurityContextHolder 也有改动,如果你的项目自定义了一些过滤器Filter可能会发现登录失效的问题。

Migrating to 6.0可以参考官方的迁移教程进行处理,因为对于spring seuciry的定制情况都不一样,这里就不展开了。

会话管理迁移 :: Spring 安全性

 

修复启动错误

spring boot从很早的一个版本开始就禁止了循环依赖,启动会报错。

你可以加入:spring.main.allow-circular-references=true来解决这个错误,更好的办法是解决项目中循环依赖情况。

Description:

The dependencies of some of the beans in the application context form a cycle:
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. 
As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

顺便提一下,基于字段变量的依赖注入很早就不推荐的包括使用@Autowired、@Resource、@Inject等

 

使用基于字段的依赖注入,随着时间的推移我们会在类中逐渐添加越来越多的其他依赖项,@Autowired我们用着很舒服,但很容易忽略类中的依赖其他类已经太多了。但是如果使用基于构造函数的依赖注入,构造函数参数会变得越来越大,我们一眼就可以察觉到哪里不对劲。让我更容易设计出符合单一职责设计的类。使用基于字段的依赖注入还会有与依赖注入容器紧密耦合,和隐藏的依赖关系的问题存在。

 

Swagger 错误

Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerException:

 

如果项目中同时存在Spring Boot 3.X 和Swagger 3.0.0 可能会出错,

报错原因
Springboot2.6以后将SpringMVC 默认路径匹配策略从AntPathMatcher 更改为PathPatternParser
Springfox 使用的路径匹配是基于AntPathMatcher的,而Spring Boot 2.6.X以上使用的是PathPatternMatcher

解决方案是加入配置:spring.mvc.pathmatch.matching-strategy=ant_path_matcher或者只用swagger 2.X版本或者换为spring doc生成文档。

 

输出的日期错误

在spring boot 3.1升级后,我发现日期格式和时间均不正确,后面经过查找资料发现spring提供一个参数。用这个参数可以修复这个问题:

logging.pattern.dateformat=yyyy-MM-dd HH:mm:ss.SSS,Asia/Shanghai

 

Redis配置错误

spring.redis.host=

spring.redis.lettuce.host=

spring.data.redis.lettuce.pool.max-active=

这些属性现在变为了:

spring.data.redis.host=

spring.data.redis.lettuce.pool.max-active=

 

分布式Session存储

这个项目用到了spring session redis来存储会话,

还需要修改一下配置:

spring.session.store-type=redis
替换为:server.servlet.session.persistent=true

你项目如果用到了FindByIndexNameSessionRepository会导致注入不成功,启动失败。需要配置改成:spring.session.redis.repository-type=indexed

或者使用对应的注解。但目前为止,我还没有发现官方有关此处改动的文档说明。

如果你的项目深入用到了spring session redis + spring security,比如请参考官方的示例进行升级:

spring-session/spring-session-samples at main · spring-projects/spring-session (github.com)

 

 

Spring Cloud版本

spring boot 3.1对应的Cloud版本是2022.0.2

 

升级后部分Cloud组件也有的属性变化,这里拿常见的feign举例。例如:

feign.circuitbreaker.enabled=true

变为:spring.cloud.openfeign.circuitbreaker.enabled=true

feign.okhttp.enabled=true

变为:spring.cloud.openfeign.okhttp.enabled=true

 

根据你使用的组件去官方文档按Ctrl+F搜索一下关键词,基本上就能找到新的对应属性。

 

如果你的Cloud版本很早是Netflix版本,有ribbon和hystrix等组件,这两个现在被spring cloud loadbanlencer和resilience4j替换了。

随便说下Spring Cloud Netflix进入维护模式是不包括Eureka的,那些说Spring Cloud被全盘抛弃,建议你Spring Cloud Alibaba的大概是培训班、卖课的说辞。

这里不是说Spring Cloud Alibaba不好用,我只是讨厌某些卖课机构、无良自媒体的胡编乱造。请以Spring官方信息为准。

Spring Cloud Netflix部分组件进入维护模式,官方也给出了替代方案:

Spring Cloud Greenwich.RC1 available now

 

 

参考资料:

Spring Boot 3.0 Migration Guide · spring-projects/spring-boot Wiki (github.com)

Migrating to 6.0 :: Spring Security

Spring Boot 3.1 Release Notes · spring-projects/spring-boot Wiki (github.com)

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章