Spring Boot 4 来了,很多团队开始焦虑:现有项目如何升级,升级要多久?
上周,我用 excel-spring-boot-starter 项目测试了一下迁移工具。
这是个 Pig 生态的 Spring Boot Starter,基于 EasyExcel** 封装 Excel 导出功能。20 个 Java 类,10 个测试类。
因为确实这次 SpringBoot4 的依赖包变更改动较多,手动迁移的话,查文档、改代码、调测试...保守估计 1-2 天。但用工具,10 分钟搞定。
OpenRewrite** 和 Arconia 这两个工具,真的能把 Spring Boot 升级从"噩梦"变成"自动化"。
Spring Boot 4 升级的三大难题
难题 1:依赖地狱
Spring Boot 4 不是简单的版本号跳跃,它带来了整个技术栈的升级:
- Spring Boot 模块化:依赖 artifactId 大量变更
- Spring Framework 7:核心框架大版本升级
- JUnit 6:测试框架从 5 升级到 6
- Testcontainers 2:容器测试工具大版本跳跃
- Jackson 3**:JSON 序列化库的破坏性升级
每个依赖都可能带来 API 变化,手动一个个查文档、改代码,光想想就头疼。
难题 2:API 破坏性变更
Spring Boot 4 有大量不兼容的 API 变更:
- 配置属性调整(如
spring.jackson.datetime.*移到了新位置) - 废弃 API 替换(字段注入改构造器注入)
- 类型重命名(
ObjectMapper→JsonMapper)
这些改动散布在几百个文件里,手动查找替换?容易漏,还容易改错。
而且手动操作还有隐患:遗漏、改错、引入新 Bug。每次发版都提心吊胆。
对于初中级开发者来说,最头疼的是:不知道改哪些,也不知道改对了没有。
OpenRewrite:自动化迁移的"黑科技"
什么是 OpenRewrite?
OpenRewrite 是个开源的自动化重构工具。核心就一点:理解你的代码,而不是简单的文本替换。
传统的查找替换:
# 这样改很危险
find . -name "*.java" -exec sed -i 's/javax./jakarta./g' {} ;
可能会把注释、字符串里的 javax. 也改了,甚至破坏代码。
OpenRewrite 的做法:
- 把代码解析成 AST(抽象语法树)
- 理解代码的语义和结构
- 精确地修改需要改的地方
- 生成更新后的代码
举个例子,它能识别出:
- 这是一个
import语句 → 需要替换 - 这是字符串中的文本 → 不需要替换
- 这是注释中的说明 → 不需要替换
这就是为什么它能做到 90-95% 的自动化覆盖率。
Recipe 机制:预定义的迁移规则
OpenRewrite 的核心是 Recipe(配方)机制。
想象一下,升级 Spring Boot 就像做菜:
- 手动升级 = 自己研究怎么切菜、炒菜、调味
- OpenRewrite = 用现成的菜谱,一步步照着做
Spring Boot 4 的迁移 Recipe 已经内置了:
- Spring Framework 7 升级规则
- JUnit 5 → 6 迁移规则
- javax → jakarta 替换规则
- 配置属性迁移规则
- 最佳实践应用(如字段注入 → 构造器注入)
你不需要知道每个细节,工具已经帮你总结好了。
工作流程
整个流程是这样的:
源代码
↓
解析为 AST(理解代码结构)
↓
应用 Recipes(执行迁移规则)
↓
生成更新后的代码
↓
你审查变更(git diff)
工具负责 90-95% 的脏活累活,你只需要:
- 配置插件
- 执行命令
- 审查变更
- 处理剩余的 5-10%
快速迁移 Arconia CLI**(最快)
Arconia 是基于 OpenRewrite 的命令行工具,专门为 Spring Boot 迁移优化。
brew 安装:
brew install arconia-io/tap/arconia-cli
Windows 用户:
# 直接从 GitHub 下载最新 release
# https://github.com/arconia-io/arconia-cli/releases
# 下载 arconia-cli-windows-amd64.exe
# 然后在命令行运行
arconia-cli-windows-amd64.exe update spring-boot --to-version 4.0
使用:
# 一键迁移到 Spring Boot 4.0
arconia update spring-boot --to-version 4.0
就这么简单。
工具会自动:
- 扫描项目
- 识别当前 Spring Boot 版本
- 应用所有必要的 recipes
- 更新代码和配置
优势:
- 零配置,开箱即用
- 最快速,适合快速验证
从代码看工具威力
案例 1:构造器注入替代字段注入
Spring Boot 4 推荐使用构造器注入,而不是字段注入。这是一个最佳实践,但手动改很麻烦。
迁移前(Spring Boot 2.x/3.x):
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return ResponseEntity.ok(userService.findById(id));
}
}
迁移后(Spring Boot 4):
@RestController
@RequestMapping("/api/users")
publicclass UserController {
privatefinal UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return ResponseEntity.ok(userService.findById(id));
}
}
变化解读:
- 移除了
@Autowired注解 - 字段改为
final(不可变,更安全) - 添加了构造器注入
为什么这样更好:
- 依赖关系更清晰(一眼看出这个类需要什么)
- 测试更容易(可以直接 new 对象,不需要 Spring 容器)
- 不可变性(
final字段不会被意外修改)
OpenRewrite 会自动帮你完成这个转换,整个项目几百个类,全部自动处理。
案例 2:JUnit 测试迁移
JUnit 从 5 升级到 6,API 有变化。
迁移前(JUnit 5):
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class UserServiceTest {
@Test
public void testFindUser() {
// 测试代码
}
}
迁移后(JUnit 6):
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest
class UserServiceTest { // public → 默认访问权限
@Test
void testFindUser() { // public → 默认访问权限
// 测试代码
}
}
变化解读:
- JUnit 6 的测试类和方法不再需要
public - 包路径可能有调整
- 部分断言方法的参数顺序调整
这些细节,手动改很容易漏。OpenRewrite 自动搞定。
迁移 excel-spring-boot-starter
我实际测试了 excel-spring-boot-starter 项目的迁移,这是一个 Pig 生态的 Spring Boot Starter 项目,基于 EasyExcel 和 FastExcel 封装了 Excel 导出功能。
测试过程:
# 克隆项目
git clone git@github.com:pig-mesh/excel-spring-boot-starter.git
cd excel-spring-boot-starter
# 一键迁移
arconia update spring-boot --to-version 4.0
项目规模:
- 约 20 个 Java 类(Starter 项目,规模较小)
- 10 个测试类
- 核心功能:Excel 导出自动配置、注解处理、模板引擎
自动处理的内容:
- Spring Boot 依赖升级(3.x → 4.0),主要是依赖 artifactId 的变更
- 自动配置类的构造器注入改造
- 测试类的 JUnit 版本升级
- 配置属性的命名空间调整
这些artifactId变更,没有自动化工具,根本不知道如何迁移
这个案例说明,即使是小型 Starter 项目,自动化工具也能大幅提升效率。对于更大的业务项目,效果会更明显。
避坑指南
- 2.x → 3.x → 4.0(分步升级)
- 每次大版本跳跃都有破坏性变更
- 分步升级更容易定位问题
- OpenRewrite 的 recipes 也是按版本设计的