博客 / 詳情

返回

Dante Cloud 升級 Spring Boot 4 經驗分享

Java 開源圈 2025 年最引人注目的事情之一,莫過於 Spring Framework 7 和 Spring Boot 4 的發佈。Dante Cloud 微服務雲原生基座項目核心定位之一,就是“極盡努力與 Spring 生態的標準規範保持一致”,所以也同步開啓了 適配 Spring Boot 4.X 的 Dante Cloud v4 版本的開發工作。

從 Spring Boot 4 第一個正式版本發佈至今也有一個月了,Dante Cloud v4 版本也同步發佈了 5 個 milestone 版本,在這個過程也積累了一些升級 Spring Boot 4 的經驗,在 Spring Boot 4.0.1 發佈之際,與大家分享,希望大家在後續的升級過程中儘量必坑。

介紹 Spring Framework 7 和 Spring Boot 4 新特性的文章已經非常多了,本文是從實戰角度出發,結合自己的實際升級經驗,對目前升級 Spring Boot 4 進行一個階段總結。

一、 “免責聲明”

説是“免責聲明”其實是開玩笑,其實主要是一些注意事項:

因為每個人的項目規模以及對 Spring Boot 使用深入度的不同,在升級 Spring Boot 4 時的工作量可大可小。

例如:

  • 你的項目完全是可以脱離 Spring 環境獨立使用的組件,僅是定義了一個 Starter 方便 Spring Boot 環境使用,那麼升級 Spring Boot 4 的工作量會非常小。
  • 你的項目深度使用 Spring Boot,Spring Boot 特性用得的非常多,主要使用 Spring Boot 推薦的技術開發,甚至是多模塊共享的多工程環境,那麼工作量一定不小。

所以,升級 Spring Boot 4 之前,還是要結合自己的實際情況,具體分析判斷。學會舉一反三,切勿盲從。

二、 New Moduler Design

雖然説 Spring Framework 7 和 Spring Boot 4 新特性很多,但是代碼管理以及兼容性做得非常好,對於使用者來説基本是“無感知”的。對現有代碼影響微乎其微,想使用就用不想使用就不用

“New Moduler Design” 這一項對於開發者使用的影響確實最直接的,也是個人認為升級 Spring Boot 4 工作量最大的一項。

1. 為什麼要重新設計模塊?

長久以來,Spring Boot 一直會收到詬病的點,就是啓動性能方面不理想。Spring Boot 的核心模塊 spring-boot-autoconfigure 是影響啓動性能重要因素之一(當然還有其它因素以及其它 autoconfigure 類型的模塊影響)。

隨着 Spring Boot 的不斷髮展,集成的相關組件或技術就越來越多。每一項組件或技術的集成,都需要實現相關的自動配置以便實現各種技術的“可插拔”,而這些配置代碼都放置在spring-boot-autoconfigure

這樣做的好處就是:

  • 放在同一個模塊好管理好維護。
  • 可以更加方便的控制各種配置類和 Bean 的注入先後順序。

這樣做的壞處就是:

  • Spring Boot 應用啓動時,需要掃描所有的配置類和 Bean,分析其中啓動順序以及生效的條件等。Spring Boot 支持的內容越多,spring-boot-autoconfigure 就越臃腫,那麼啓動時需要分析的內容就越多,就會影響啓動的性能
  • spring-boot-autoconfigure 中的內容,不管你實際項目中是否用到,啓動時都是需要進行分析和條件判斷。

因此,Spring Boot 4 最大變化之一,就是將 spring-boot-autoconfigure 中的內容,拆分成各自獨立的模塊。拆分出來的模塊,統一以 spring-boot-<technology> 格式進行命名。

例如:原本 WebClient 的默認配置代碼是放置在 spring-boot-autoconfigure 模塊中,被拆分出來之後,WebClient 默認的配置代碼就被放置到 spring-boot-webclient 模塊中

在實際開發中就不要統一依賴 spring-boot-autoconfigure,根據需要用到那種技術就手動依賴相關的 spring-boot-<technology> 模塊或者對應的 Starter。

這樣可以極大地減少啓動時配置類的掃描和分析,以達到提升性能的目的

2. 拆分後如何控制配置注入順序?

這個問題其實是 spring-boot-autoconfigure代碼拆分後的最大問題,為了解決這個問題 Spring Boot 在 @AutoConfiguration 中新增兩個屬性:aftername beforename。通過這兩個屬性,你可以直接以“字符串”形式配置其它模塊某個配置類的完整類路徑。

這樣就不用再通過依賴模塊,配置具體 Class 的方式控制配置順序,而且解決了跨模塊控制配置類順序的問題

3. 為什麼升級工作量大?

工作量大不大,請結合“免責聲明”章節內容,還是要結合項目實際情況而定,切勿無腦抬槓。

Spring Boot 4 “New Moduler Design”帶來了性能的提升,同時也給升級帶來了最大阻礙。

原本所有代碼都是放置在 spring-boot-autoconfigure中,工程中默認就依賴了。不管是你自己的配置類中自動注入相關的配置,還是代碼中用到了其中的代碼都非常方便。

Spring Boot 4 將spring-boot-autoconfigure中的代碼拆分為不同模塊之後,其中還會涉及到類路徑的變化。

如果你的代碼用到了很多 spring-boot-autoconfigure 中的代碼,那麼在升級 Spring Boot 4 時,不僅要找打原有代碼所在的新模塊,還要去找對應的類在新模塊中所在的包。因為沒有統一的可以索引的地方,只能自己慢慢地找。

作者是直接將 Sping Boot 的源碼下載下來,找不到代碼時就在 Spring Boot 源碼中全文搜索。

4. 帶來的啓示

原本 Spring Boot 2.X 升級 3.X 時,除了一些特性的變化外,整體的代碼結構和包路徑還是基本保持一致,這種情況下還可以考慮一下兼容問題。

因為,Spring Boot 4 中會出現很多類的包路徑變化的情況,這樣就很難考慮兼容的問題。(類路徑都變了,考慮兼容還有什麼意義)

所以,如果你的項目原本需要考慮兼容性的,升級 Spring Boot 4 時就別考慮兼容問題了,都是無用功。

三、 周邊生態的適配

升級 Spring Boot 4 另一項重要工作,就是你所使用到的周邊第三方組件的適配。之所以説這項工作重要,原因其實在前面的內容中已經説到了,就是:Spring Boot 4 中很多類的包路徑變了,這是沒有什麼好辦法進行兼容處理的,只有等者周邊生態軟件的適配。

如果不適配會直接影響代碼運行的

以 Dante Cloud 項目為例,需要等待適配的周邊,以及相關的進度如下:

  • Spring Cloud Alibaba:已經有 Committer 提交了適配代碼,因為項目在考慮徹底刪除對 Bootstrap 模式的支持,所以還沒有發測試或者正式版本
  • Spring Cloud Tencent:項目團隊人員少,在等着社區 Committer 貢獻適配代碼
  • Spring Boot Admin:正在適配中
  • Resilience4j:還沒有看到相關計劃
  • Jasypt Spring Boot Starter:時隔幾年才剛發佈適配 Spring Boot 3.5 版本,適配 Spring Boot 4 還得等

四、 Jackson3

Spring Boot 4 中另一項比較有影響的變化就是開始使用 Jackson 3。

Jackson 3 主要的變化有:

  1. com.fasterxml.jackson 變為 tools.jackson。所以,如果你深度使用 Jackson 還想用 Jackson3,那麼會大量修改包路徑的工作
  2. new ObjectMapper 已經不推薦使用。需要使用以下方式創建:
this.objectMapper = JsonMapper.builder()
        .enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)
        .enable(JsonReadFeature.ALLOW_SINGLE_QUOTES)
        .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
        .build();
  1. 註解相關配置方式變化
JsonMapper.builder()
        .changeDefaultPropertyInclusion(incl -> incl.withValueInclusion(JsonInclude.Include.NON_NULL))
        .build();
  1. 部分原有需要手動關閉的配置,目前 Jackson3 已經修改默認關閉
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
  1. Jackson3 所有方法統一拋出 JacksonException

注意事項

  1. jackson3 中,還是使用的 jackson 2.x annotation 模塊,所以如果使用了 jackson 註解,註解的座標還是com.fasterxml.jackson,所以在修改 jackson 3 包名時,如果想用 IDE 進行全局包路徑替換一定要謹慎,以防改錯。
  2. Spring Boot 4 還保留了 Jackson 2 的支持。Jackson 2 的代碼均放置在 **.Jackson2.** 包下面,而 Jackson 3 的代碼均放置在 **.Jackson.** 包下面

五、 commons-lang3

Spring Boot 4 基礎依賴的 commons lang3 已經升級至 3.19.0。

自 commons lang3 3.18.0 版本起,String 相關操作工具類有了較大變化,原有 StringUtils.XX,拆分為 Strings.CI.XX Strings.CS.XX

因此,還會涉及大量包路徑的修改

升級至 3.19.0,原有方法 StringUtils.XX 仍然可用,不過又有大量過時告警。

六、 JSpecify

Spring Boot 4 中,全面引入 JSpecify 相關注解進行空值標註。

所以建議將原有 Spring 提供的 Nullable 以及 IDEA 提供的 NotNull 註解全部替換為 JSpecify。

注意:如果你實現或者擴展了 Spring 或者相關組件的一些方法,建議檢查一下是否已經變換為 JSpecify 註解。如果變換了建議將自己的實現方法同步修改一下

七、 API 版本

Spring Boot 4 中最吸引人的另一個功能,莫過於對於 API 版本的支持。Dante Cloud 也同步增加了對 API 版本動態鑑權的支持。

Spring Boot 4 API 版本,支持 Query 參數版本、路徑版本、以及請求 Header 版本三種,獲取版本方式。需要結合自己的實際進行修改。

如果你想支持 API 版本,同時支持 API 接口的動態鑑權,那麼會有一定的工作量

八、 Undertow 移除

Undertow 作為一款高性能的 Web 容器,深受用户喜愛。但是因為對 Servlet 6.1 支持度較差,不符合 Spring Boot 的發展方向,所以在 Spring Boot 4 中已經將 Undertow 相關的支持移除。

因為 Dante Cloud 一直以來都在使用 Undertow 作為 Web 容器,所以不得不在新版本中進行更換。最早是更為換 Tomcat,但是 Tomcat 過於厚重、性能優化配置繁瑣、啓動速度明顯慢,所以最終還是更換為更加輕量的 Jetty。

總結

整體而言,升級 Spring Framework 7 和 Spring Boot 4 機制方面的變化,對於用户來説是“無感的”。Dante Cloud 升級 Spring Boot 4 的工作,其實大量的工作都是在修改“包路徑”。

升級 Spring Boot 3.X 時,大部分人還抱着“懷疑”、“觀望”的態度。但是到了 Spring Boot 4.X,很多開源社區在正式版未發佈之前就已經開始着手適配工作。可見其對於用户吸引力有多打。

Spring Boot 4 機制以及對性能的提升,特別是對 JDK 25 的支持,非常值得一試。 目前升級 Spring Boot 4 最大的難點就在於周邊生態的適配度。


項目地址:

Gitee:https://gitee.com/dromara/dante-cloud

Github:https://github.com/dromara/dante-cloud

Gitcode:https://gitcode.com/dromara/dante-cloud

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.