Spring Boot 4 升级为什么卡在 Jackson 3?包名、配置与兼容迁移指南
技术范围:Java 17+、Spring Boot 4.x、Spring Framework 7、Jackson 2/3、Spring MVC
一、先说结论:Boot 4 升级不只是改版本号
不少团队把 Spring Boot 3.x 的版本号改成 4.x 后,遇到这样的编译或运行问题:
com.fasterxml.jackson.databind.ObjectMapper相关代码无法直接适配新的自动配置;@JsonComponent、定制序列化器、ObjectMapperBean 配置需要调整;- 项目同时存在 Jackson 2 和 Jackson 3,导致序列化结果、消息转换器或第三方组件行为不一致;
- 升级后日期、数字、空值、字段命名的 JSON 输出发生变化。
核心原因之一是 Spring Boot 4 默认转向 Jackson 3,而 Jackson 3 不只是“原来的库升级一个大版本”:包名、部分 API、默认行为和 Spring Boot 集成方式都发生了变化。
如果只记住一个升级策略,我建议:先盘点 JSON 边界和依赖,再迁移 Jackson;先通过契约测试,再切换生产流量。
官方资料:2025-11-20 Spring Boot 4.0.0 发布公告;Spring Boot 4 迁移指南。
二、Jackson 2 与 Jackson 3 最直观的区别
Spring 官方在 2025-10-07 专门解释过 Jackson 3 集成策略:Boot 4 和 Framework 7 默认使用 Jackson 3,同时暂时保留 Jackson 2 的迁移通道。
| 维度 | Jackson 2 | Jackson 3 |
|---|---|---|
| Maven 坐标(典型) | com.fasterxml.jackson.core:jackson-databind |
tools.jackson.core:jackson-databind |
| 核心类包名 | com.fasterxml.jackson.databind.ObjectMapper |
tools.jackson.databind.json.JsonMapper |
| Spring Boot 4 默认 | 兼容性支持(已弃用) | 首选与默认 |
| 注解包 | com.fasterxml.jackson.annotation |
多数常用注解仍保留这个包名 |
| 迁移重点 | 旧 API 与配置 | 新 API、默认值和依赖链 |
不要把所有 com.fasterxml.jackson.* 一键替换为 tools.jackson.*。例如 jackson-annotations 保留原来的 groupId 与包名,这是官方明确的兼容例外。
也不要认为“依赖树中出现 Jackson 2 就一定冲突”:官方允许两代库并存,真正要检查的是哪个 Mapper 和哪个 HTTP MessageConverter 在处理请求。
三、第一步:用依赖树确认实际版本
Maven 项目执行:
mvn dependency:tree -Dincludes=com.fasterxml.jackson.core:*,tools.jackson.core:*
如果 Maven 插件或 Shell 对参数通配符处理不一致,可先使用:
mvn dependency:tree | grep -Ei 'jackson|spring-boot'
Windows PowerShell 可以使用:
mvn dependency:tree | Select-String 'jackson|spring-boot'
重点核对:
- Spring Boot BOM 实际管理的版本。
- Web、Security、Redis、OpenFeign、HTTP 客户端等组件是否引入旧 Jackson。
- 是否手工声明了旧版
ObjectMapperBean。 - JSON 序列化工具类是否硬编码 Jackson 2 类型。
切勿为消除依赖树中的 Jackson 2 而盲目排除所有传递依赖,某些第三方组件仍依赖旧版解析器。要结合其兼容说明逐个处理。
四、第二步:改造 JsonMapper,而不是只改 import
Spring Boot 4 的 spring-boot-starter-json 使用 Jackson 3;当 Jackson 3 在类路径上时,Boot 会自动配置 JsonMapper Bean。
在 Spring Boot 3 时代,很多项目这样使用:
import com.fasterxml.jackson.databind.ObjectMapper;
@Service
public class JsonService {
private final ObjectMapper mapper;
public JsonService(ObjectMapper mapper) {
this.mapper = mapper;
}
}
迁移到 Jackson 3 时,更推荐围绕 JsonMapper 建立新代码:
import tools.jackson.databind.json.JsonMapper;
@Service
public class JsonService {
private final JsonMapper mapper;
public JsonService(JsonMapper mapper) {
this.mapper = mapper;
}
public String toJson(Object value) {
return mapper.writeValueAsString(value);
}
}
以上代码是核心依赖注入片段,假设项目使用 Spring Boot 4 的默认 Jackson 3 自动配置,@Service 等 Spring 注解需正常导入。
为什么优先注入容器的 Mapper?因为它承载了全局日期格式、模块注册、属性配置等统一行为。到处 new JsonMapper() 可能造成控制器返回 JSON 与后台任务输出 JSON 不一致。
五、第三步:检查注解与配置迁移
1. @JsonComponent 更名
Spring Boot 4 中,原来的 @JsonComponent 更名为 @JacksonComponent,@JsonMixin 对应 @JacksonMixin。如果你有自定义序列化器和反序列化器,需要检查相关类型和注册方式,而不是只修改注解名称。
2. JSON 配置层级发生变化
例如原来位于 spring.jackson.read.*、spring.jackson.write.* 的 JSON 专属配置迁移到:
spring:
jackson:
json:
read:
# 在这里配置目标版本支持的具体读取选项
write:
# 在这里配置目标版本支持的具体写入选项
上面的 YAML 仅展示属性层级,不是可以直接复制的完整配置。具体枚举属性名和取值必须对照目标 Boot 4.x 的配置元数据核实。
3. 默认行为改变怎么办?
如果现有客户端依赖 Jackson 2 的历史序列化行为,可以临时启用:
spring:
jackson:
use-jackson2-defaults: true
该选项是让 Jackson 3 的默认行为尽可能接近 Spring Boot 3 中的 Jackson 2,并不保证所有 JSON 完全相同。尤其是日期格式、自定义序列化器、多态类型、空值、浮点数等,仍应通过真实请求与历史快照对比。
官方迁移指南:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide
六、暂时迁不了 Jackson 3,能否先升级 Spring Boot 4?
可以作为过渡方案,但不能当作长期策略。
Spring Boot 4 仍提供已弃用的 spring-boot-jackson2 模块,供无法立刻迁移的应用使用。官方示例依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-jackson2</artifactId>
</dependency>
但如果默认的 Jackson 3 自动配置仍在类路径上,不能指望只加这个依赖就能把整个应用“切回 Jackson 2”。需要根据具体 Starter 依赖树排除不需要的 Jackson 3 自动配置模块,并核实 MVC 消息转换器的实际选择。
Jackson 2 兼容属性使用 spring.jackson2 前缀。官方已明确这条兼容路径将来会移除,所以应同时建立迁移计划,而不是永久停留在双版本状态。
迁移路线建议
原系统:Spring Boot 3 + Jackson 2
│
├── 路线 A:直接升级 Boot 4 + Jackson 3
│ ↓
│ 契约测试与回归
│
└── 路线 B:Boot 4 + 临时 Jackson 2
↓
单独迁移 Jackson 3
↓
删除兼容依赖
对业务量大、第三方组件多的系统,路线 B 有时更容易隔离变更范围;但它也增加了过渡期维护成本。
七、不要只测“应用能启动”,要测 JSON 契约
升级最危险的结果不是启动失败,而是服务正常启动,但客户端看到的 JSON 变了。
建议至少覆盖下面的场景:
| 场景 | 测试重点 |
|---|---|
| 日期时间 | 时区、偏移量、精度、ISO 格式 |
| 金额与数字 | BigDecimal、浮点精度、整数范围 |
| null / 缺失字段 | 默认值、校验、字段是否输出 |
| 枚举 | 字符串、数字、大小写 |
| 多态对象 | 类型标识、白名单、反序列化安全 |
| Redis 缓存 | 旧序列化数据是否还能读 |
| 消息队列 | 旧生产者和新消费者是否兼容 |
| 对外 API | 手机端、第三方客户端是否依赖历史格式 |
一个简洁的 MockMvc 测试思路:
@SpringBootTest
@AutoConfigureMockMvc
class JsonContractTests {
@Autowired
MockMvc mvc;
@Test
void productJsonContract() throws Exception {
mvc.perform(get("/api/products/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1))
.andExpect(jsonPath("$.price").exists());
}
}
上面是测试结构示例,依赖实际项目的控制器、数据准备与对应 Boot 4 测试模块配置;不能将其视为已在某个具体工程运行通过的完整测试。更推荐把升级前真实响应保存为脱敏的 JSON 契约样本,升级后对比关键字段和值类型。
八、生产升级前的六项检查
- 确认运行基线:Spring Boot 4 支持 Java 17,别把“支持 Java 25”误解为“最低要求 Java 25”。
- 看迁移指南:Boot 4 不止 Jackson 变化,还有模块拆分、Spring Framework 7、JSpecify 和 API 版本化等。
- 检查第三方 Starter:特别是 Spring Cloud、Security、Redis、数据库与监控依赖的兼容矩阵。
- 验证 Mapper 来源:确认控制器、工具类、消息消费者是否使用预期的 Jackson 版本。
- 灰度与回滚:保存升级前 JSON 契约和配置;必要时先灰度流量。
- 监控异常:重点观察 400、415、500、反序列化异常、客户端兼容问题。
九、常见问题
Spring Boot 4 必须使用 Java 25 吗?
不需要。Spring Boot 4.0 官方发布说明明确保留 Java 17 兼容性,并增加 Java 25 一等支持。
Jackson 3 能直接读取所有 Jackson 2 生成的 JSON 吗?
不能一概而论。常规 JSON 数据可能兼容,但类型信息、自定义序列化器、日期格式和历史二进制/缓存数据需要逐项验证。
能不能把 Jackson 2 和 Jackson 3 同时放在一个应用里?
官方支持迁移期并存,但要避免不同 Mapper、HTTP 转换器和缓存序列化器无意间混用。双版本并存是过渡手段,不是默认推荐的最终状态。
Spring Boot 4 是 2026 年 11 月刚发布的吗?
不是。Spring Boot 4.0.0 于 2025 年 11 月 20 日 发布。本文聚焦的是目前仍具有工程价值的 Jackson 3 迁移问题,不把旧发布当成当天新闻。
总结
Spring Boot 4 升级中的 Jackson 3 问题,本质上是框架默认行为与应用长期积累的 JSON 契约发生交汇。正确顺序不是“全局替换包名 → 编译成功 → 直接上线”,而是:
依赖盘点 → Mapper 与配置迁移 → JSON 契约回归 → 灰度发布 → 清理过渡依赖。
如果你正在维护长期运行的 Java 系统,这些工作比追逐最新版本号更重要。

浙公网安备 33010602011771号