主版本升級方法論
框架主版本升級(如 Spring Boot 3.x → 4.x)的標準化流程與最佳實踐。
本方法論基於實際升級經驗持續改進。
為什麼需要特殊的升級策略?
主版本升級通常包含大量 breaking changes:
- API 重新命名或移除
- 依賴套件變更(如 Jackson 2 → 3 改變了套件名稱)
- 配置方式改變
- 預設行為變更
直接升級(在現有專案上修改版本號)會導致:
- 大量編譯錯誤同時出現,難以定位
- 可能遺漏某些配置變更
- 升級後無法啟動時,難以判斷原因
- 沿用舊的配置方式,錯過官方建議的新做法
推薦策略:從乾淨框架逐步移植
核心原則
每一步都要有可驗證的基準點
不是「改到能編譯為止」,而是「從能運作的狀態開始,逐步添加功能」。
策略比較
| 項目 | 直接升級 | 從乾淨框架移植 |
|---|---|---|
| 起點 | 現有專案(可能有歷史包袱) | Spring Initializr 產生的乾淨專案 |
| 編譯錯誤 | 一次全部出現 | 逐步出現,易定位 |
| 配置正確性 | 可能沿用舊配置 | 使用官方建議配置 |
| 問題定位 | 困難 | 容易(每步可驗證) |
| 工作量 | 表面上較少 | 表面上較多,但總體更可控 |
標準升級流程
Phase 0: 準備工作
目的:充分了解升級範圍,避免「事後發現遺漏」。
- [ ] 回退到穩定版本(確保有乾淨的起點)
- [ ] 建立升級紀錄文檔
- [ ] 盤點現有專案
- [ ] Java 模組清單(所有 package 目錄)
- [ ] resources 目錄內容(含 META-INF)
- [ ] 依賴清單(區分 api/implementation/compileOnly)
- [ ] 研究官方 Migration Guide
- [ ] 閱讀主框架 Migration Guide
- [ ] 閱讀相關框架 Migration Guide(Security, Hibernate 等)
- [ ] 建立「預期 Breaking Changes 清單」
- [ ] 標註影響的模組
- [ ] 區分「必須修復」vs「可延後處理」
經驗教訓
遺漏 META-INF/spring.factories 會導致啟動失敗但難以定位。事前完整盤點可避免此類問題。
Phase 1: 產生乾淨的消費者專案
目的:取得新版本的正確依賴配置,作為參考範本。
- [ ] 使用 Spring Initializr 產生專案
- 選擇目標 Spring Boot 版本
- 選擇所有需要的依賴
- [ ] 驗證可正常編譯和啟動
- [ ] 記錄 starter 名稱差異(與舊版對比)
- [ ] 記錄新增/移除的依賴
Phase 2: 建立 Library 專案骨架
目的:建立可編譯的 library 專案結構。
- [ ] 建立 java-library 專案結構
- [ ] 配置 build.gradle.kts
- plugins(java-library, maven-publish)
- repositories
- dependencies(參考 Phase 1 的配置)
- publishing 配置
- [ ] 配置 Composite Build(消費者引用 library)
- [ ] 驗證空專案可編譯
Phase 3: 逐模組移植 Library
目的:分批移植,每批都驗證,及早發現問題。
重要原則
不要一次複製所有模組。分批移植,每批:複製 → 編譯 → 修復 → 測試 → 驗證。
建議的移植順序(依賴關係由低到高):
批次 1: 基礎工具(無外部依賴)
- [ ] env/ - 環境配置
- [ ] bean/ - Bean 工具
- [ ] converter/ - 類型轉換器
→ 編譯驗證
批次 2: 序列化模組
- [ ] json/ - JSON 處理(可能有 Jackson Breaking Changes)
- [ ] xml/ - XML 處理
- [ ] csv/ - CSV 處理
→ 編譯驗證 + 執行單元測試
批次 3: 安全模組
- [ ] auth/ - 認證
- [ ] oauth2/ - OAuth2
- [ ] security/ - 安全工具
→ 編譯驗證 + 執行單元測試
批次 4: 資料模組
- [ ] entity/ - Entity 工具
- [ ] jpa/ - JPA 工具
- [ ] search/ - 搜尋
- [ ] cache/ - 快取
→ 編譯驗證 + 執行單元測試
批次 5: 其他模組
- [ ] file/, mail/, web/, http/, image/ 等
→ 編譯驗證 + 執行單元測試
批次 6: resources
- [ ] META-INF/(spring.factories 等)
- [ ] 其他 resources
→ 消費者啟動驗證
Phase 4: 整合驗證
目的:確保 library 可被消費者正常使用。
- [ ] 消費者專案引用 library
- [ ] 移除消費者的重複依賴
- [ ] 驗證消費者可啟動
- [ ] 驗證基本功能(Health check 等)
Phase 5: 移植 Application
目的:移植應用程式程式碼。
- [ ] 複製 Java 原始碼
- Entity → Repository → Service → Controller
- 每層複製後編譯驗證
- [ ] 複製 resources
- application.yml
- 其他配置檔
- [ ] 修復 Breaking Changes
- [ ] 執行單元測試
- [ ] 驗證啟動成功
Phase 6: 驗收
目的:確保升級後系統正常運作。
- [ ] 單元測試全部通過
- [ ] 功能驗收
- API 端點可存取
- 認證授權正常
- 資料庫操作正常
- [ ] 效能檢查(如適用)
Phase 7: Deprecation 處理(可選)
目的:處理編譯警告,為未來版本做準備。
- [ ] 處理 deprecation warnings
- [ ] 評估可選遷移項目
- [ ] 記錄決策和理由
區分 Breaking Change vs Deprecation
| 類型 | 定義 | 處理時機 | 範例 |
|---|---|---|---|
| Breaking Change | 不修就無法編譯/運作 | Phase 3-5 立即修復 | Jackson 套件名稱變更 |
| Deprecation Warning | 可編譯但有警告 | Phase 7 處理 | EnvironmentPostProcessor 標註 deprecated |
| 評估項目 | 需研究是否遷移 | Phase 7 評估 | JJWT vs Nimbus |
判斷原則
如果不處理會導致編譯失敗或運作異常,就是 Breaking Change,必須立即處理。
Library vs Application 的差異
| 項目 | Library | Application |
|---|---|---|
| Gradle Plugin | java-library | org.springframework.boot |
| Main Class | 無 | 有 |
| 可獨立啟動 | 否 | 是 |
| 驗證方式 | 透過消費者驗證 | 直接啟動驗證 |
| 依賴 Scope | api(傳遞給消費者) | implementation |
| 發布方式 | Maven publish | WAR/JAR 部署 |
| bootJar Task | 停用 | 啟用 |
Library 專案的特殊考量
Spring Initializr 不產生 library 專案,它只產生可啟動的應用程式。
因此,升級 library 時:
- 先用 Spring Initializr 產生消費者應用程式
- 參考消費者的依賴配置
- 手動建立 library 專案結構
升級紀錄的重要性
每次主版本升級都應該建立升級紀錄文檔,包含:
1. 升級計劃(事前)
- 升級目標和範圍
- 分階段的步驟清單
- 預期的 breaking changes
2. 進度追蹤(過程中)
- 用 checkbox 標記完成狀態
- 記錄實際操作和發現
3. Breaking Changes 紀錄(過程中)
- API 變更對照表
- 解決方案和程式碼範例
4. 執行紀錄(過程中)
- 按時間順序記錄操作
- 遇到的問題和解決方式
升級紀錄範本
# [框架名稱] [版本] 升級紀錄
## 升級概覽
| 項目 | 升級前 | 升級後 |
|------|--------|--------|
| ... | ... | ... |
## 升級策略
(說明採用的策略和原因)
## 事前準備
### 模組清單
(盤點結果)
### 預期 Breaking Changes
| 項目 | 影響模組 | 處理方式 |
|------|---------|---------|
| ... | ... | ... |
## 升級進度
### Phase 0: 準備工作
- [ ] ...
### Phase 1: ...
- [ ] ...
## Breaking Changes 紀錄
| 變更類型 | 舊版 | 新版 | 說明 |
|---------|------|------|------|
| ... | ... | ... | ... |
## 執行紀錄
### YYYY-MM-DD
(實際操作紀錄)
相關文檔
- Spring Boot 4.0 升級紀錄 - 實際升級案例