簡單記錄下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)

 


 

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