以下內容是 Spring Framework 6.0 的官方發佈説明(Release Notes),由 Brian Clozel 在 2024 年 10 月 28 日編輯。這份文檔非常關鍵,因為它標誌着 Spring 框架的一次重大版本升級,從 Spring 5 到 Spring 6 是一次不兼容的升級(breaking change)

下面我將為你逐部分解析這份 Release Notes 的核心信息,並解釋它的實際影響和開發者應該如何理解和應對。


項目

內容

發佈時間

2024年10月28日

最低 Java 版本

Java 17+(不再支持 Java 8/11)

技術棧遷移

javax.*jakarta.*(Jakarta EE 9+)

主要目標

支持雲原生、GraalVM 原生鏡像、AOT 編譯、虛擬線程等現代技術

這意味着:如果你還在用 Java 8 或 Spring 5.x,要升級到 Spring 6 必須先升級 JDK 和所有依賴庫。


1. Java 17+ 要求

  • 所有代碼基於 Java 17 編寫。
  • 支持 虛擬線程(Virtual Threads)(JDK 19+ 預覽功能,未來會成為核心特性)。
  • 不再支持 Java 8、11、16 等舊版本。

提示:Spring Boot 3 也基於 Spring 6,所以 Spring Boot 3 要求 Java 17+。

2. Jakarta EE 9+ 遷移

  • 所有包名從 javax.* 改為 jakarta.*
  • javax.servletjakarta.servlet
  • javax.persistencejakarta.persistence
  • javax.validationjakarta.validation
  • javax.injectjakarta.inject
  • 第三方組件也要升級:
  • Hibernate ORM 5.6+(hibernate-core-jakarta)或直接上 Hibernate 6.1+
  • Tomcat 10+ / Jetty 11+ / Undertow 2.2.19+
  • EclipseLink 3.0+

⚠️ 如果你的項目還在用 javax.servlet.*,必須全部替換為 jakarta.servlet.*,否則編譯失敗!


️ 二、被移除的功能(Removed APIs)

這些功能已被永久刪除,不能再使用:

被移除功能

替代方案

Hessian、HTTP Invoker、JMS Invoker、JAX-WS

已廢棄多年,建議使用 REST 或 gRPC

EJB 訪問支持

使用 JNDI 直接查找(JndiObjectFactoryBean

org.springframework.cache.ehcache(Ehcache 2.x)

升級到 Ehcache 3.x 或使用 JCache API(javax.cache

❗ 特別注意:Ehcache 2.x 即將停止維護,必須遷移!


1. Bean 屬性探測機制變更

  • 默認不再使用 java.beans.Introspector(性能更好)
  • 如果舊代碼依賴複雜 JavaBeans 行為,可通過配置恢復:
# META-INF/spring.factories
org.springframework.beans.BeanInfoFactory=org.springframework.beans.ExtendedBeanInfoFactory

2. 參數名推斷警告

  • LocalVariableTableParameterNameDiscoverer棄用,會打印警告。
  • 解決方法:編譯時加上 -parameters 參數(Java 8+):
javac -parameters MyClass.java
  • Kotlin 用户建議加 -java-parameters 編譯選項。

3. @Inject, @PostConstruct, @PreDestroy 包名變化

  • 新位置:
  • jakarta.inject.Inject
  • jakarta.annotation.PostConstruct
  • jakarta.annotation.PreDestroy
  • Spring 暫時仍兼容 javax.* 版本(用於兼容老 jar 包),但未來可能移除。

4. ListenableFuture 棄用

  • 推薦使用 CompletableFuture(Java 8+ 標準異步編程模型)

5. @Async 方法返回類型限制

  • 只能返回 voidFuture 子類(如 CompletableFuture
  • 其他類型(如 StringMono)會拋異常。

1. Hibernate & JPA 升級

  • 推薦使用 Hibernate 6.1+(只支持 jakarta.persistence
  • Hibernate Validator 7.0+(對應 Jakarta Bean Validation 3.0)

2. JDBC 異常翻譯改進

  • 默認使用 SQLExceptionSubclassTranslator(更準確)
  • CannotSerializeTransactionExceptionDeadlockLoserDataAccessException棄用
  • 推薦統一使用 PessimisticLockingFailureExceptionCannotAcquireLockException

3. 移除 JCA CCI 支持

  • Java EE 連接器架構(JCA CCI)已過時,被移除。

1. Servlet 容器要求

  • 必須使用支持 Jakarta EE 的服務器:
  • Tomcat 10.1+
  • Jetty 11+
  • Undertow 2.3+(注意要用 undertow-servlet-jakarta

2. 移除過時的集成

被移除

推薦替代

Apache Commons FileUpload

StandardServletMultipartResolver(基於 Servlet 3.0+)

Apache Tiles

不再推薦,建議用 Thymeleaf、Freemarker 模板引擎

FreeMarker JSP 支持

不再支持 JSP,推薦純模板或前後端分離

Spring 6 不再推薦 JSP! 推薦 RESTful 架構或現代前端框架。

3. 尾部斜槓匹配(Trailing Slash Matching)默認關閉

@GetMapping("/some/greeting")
public String greeting() { ... }
  • 以前:匹配 /some/greeting/some/greeting/
  • 現在:只匹配 /some/greeting/some/greeting/ 返回 404

✅ 解決方案(二選一):

  1. 顯式聲明兩個路徑:
@GetMapping({"/some/greeting", "/some/greeting/"})
  1. 全局開啓兼容模式:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch(true);
}
}

4. HttpMethod 從 enum 變成 class

  • 原因:為了支持自定義 HTTP 方法(如 WebDAV 的 PROPFIND
  • 影響:
// 以前
EnumSet<HttpMethod> methods = EnumSet.of(HttpMethod.GET, HttpMethod.POST);
  // 現在
  Set<HttpMethod> methods = Set.of(HttpMethod.GET, HttpMethod.POST);
  • switch 語句不能用了,改用 if-else

5. RestTemplate 要求 HttpClient 5

  • 如果你用了 HttpComponentsClientHttpRequestFactory,必須升級 Apache HttpClient 到 5.x 版本。

6. SourceHttpMessageConverter 不再默認註冊

  • 如果你用 javax.xml.transform.Source 做 XML 處理,需要手動添加:
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
  converters.add(new SourceHttpMessageConverter<>());
    // 注意順序:放在 MappingJackson2HttpMessageConverter 前面
    }
    };
    }

1. AOT(Ahead-of-Time)支持 & GraalVM 原生鏡像

  • Spring 6 為 原生編譯 打下基礎。
  • 支持在 GraalVM 中將 Spring 應用打包成原生可執行文件(啓動更快、內存更小)。
  • GenericApplicationContext.refreshForAotProcessing() 可用於預處理 bean 定義。

2. 觀測性(Observability)集成 Micrometer

  • 內置對 Micrometer Observation 的支持(1.10+)
  • 自動追蹤:
  • HTTP 客户端請求(RestTemplate / WebClient)
  • HTTP 服務端請求(MVC / WebFlux)
  • Reactor 流上下文傳播(Flux/Mono)
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-observation</artifactId>
<version>1.10+</version>
</dependency>

3. 新的聲明式 HTTP 客户端

  • 類似 Feign,但基於標準:
  • @HttpExchange(Spring MVC 風格)
  • @RSocketExchange(RSocket 風格)
@HttpExchange(url = "/api/users/{id}")
interface UserClient {
@GetExchange
User getUser(@PathVariable String id);
}

4. Spring MVC 使用 PathPatternParser(默認)

  • 更快的路徑匹配算法(來自 Spring WebFlux)
  • 可選回退到舊的 AntPathMatcher

5. Spring WebFlux 新特性

  • PartEvent:流式上傳 multipart 文件
  • ResponseEntityExceptionHandler:支持返回 RFC 7807 標準錯誤格式(Problem Details)
  • Flux<T> 返回非流式數據時不再自動收集為 List,直接逐個寫入響應

  • Servlet Mocks(如 MockHttpServletRequest)基於 Servlet 6.0 API
  • 測試類路徑需包含 jakarta.servlet-api 6.0+
  • 生產代碼仍可用 Servlet 5.0 編譯,但測試必須用 6.0+
  • 新增 setRemoteAddress() 方法用於模擬客户端 IP

✅ 總結:你需要做什麼?

任務

操作

升級 JDK

至少 Java 17(推薦 17~21)

遷移到 Jakarta EE

替換所有 javax.*jakarta.* 包名

️ 升級中間件

Hibernate 6.1 / Tomcat 10.1 / Jetty 11 / HttpClient 5

移除廢棄依賴

如 Ehcache 2.x、Commons FileUpload、Tiles

⚙️ 檢查編譯參數

-parameters 避免參數名警告

檢查 @Async 方法

返回值只能是 voidFuture

配置尾斜槓行為

明確是否開啓 setUseTrailingSlashMatch(true)

啓用觀測性

引入 Micrometer 並配置 ServerHttpObservationFilter

考慮 GraalVM

若追求極致性能,嘗試構建原生鏡像


  • Spring Framework 6 Migration Guide
  • Jakarta EE Migration Guide
  • Spring Boot 3 Release Notes
  • Micrometer Observations

如果你正在計劃從 Spring 5.3 升級到 6.0,建議:

  1. 先升級 JDK 到 17
  2. 使用工具(如 IDE 或 jdeps)掃描 javax.* 依賴
  3. 逐步替換為 jakarta.*
  4. 更新所有依賴庫版本
  5. 運行測試,修復不兼容問題

需要我幫你生成一個 Spring 5 → Spring 6 的遷移檢查清單(Checklist) 嗎?