Spring Boot 3.2 升级踩坑实录:从 2.7 迁移过来,这几个兼容性问题花了我一周
公司项目终于决定从 Spring Boot 2.7 升级到 3.2。领导说"应该没什么大问题,升个版本号而已"。我信了,然后花了一周时间填坑。
这里记录几个最耗时的兼容性问题,给准备升级的同学提个醒。
** Jakarta EE 命名空间变更**
这是最坑的。Spring Boot 3.x 依赖 Jakarta EE 9,包名从 javax.* 改成了 jakarta.*。我项目里几十个文件用了 javax.servlet、javax.persistence,全部要改。
不是简单的全局替换,有些第三方库还没迁移。比如我们用的一个老版缓存框架,内部引用了 javax.cache,升级后直接 ClassNotFound。最后只能换了个实现,或者等作者更新。
** MyBatis Plus 版本兼容**
我们用的 MyBatis Plus 3.5.2 在 Spring Boot 3.2 下启动报错,提示 Property ‘sqlSessionFactory’ or ‘sqlSessionTemplate’ are required。查了半天发现是自动配置机制变了。
解决方案:升级到 MyBatis Plus 3.5.5 以上版本,同时检查 mybatis-plus-boot-starter 的依赖是否冲突。如果用了多数据源,配置方式也有变化,需要显式指定 SqlSessionFactory。
** Jackson 日期格式化**
Spring Boot 3.2 默认的 Jackson 版本升级后,对 java.time.LocalDateTime 的序列化行为变了。之前返回的格式是 2024-01-01T12:00:00,升级后变成了带时区的 2024-01-01T12:00:00+08:00。
前端同学直接炸了,说解析失败。临时解决方案是在 application.yml 里加:
spring: jackson: serialization: write-dates-as-timestamps:falsedate-format: yyyy-MM-dd HH:mm:ss** 原生镜像编译(GraalVM)**
领导听说 Spring Boot 3 支持 AOT 编译,启动快内存小,非要我试试。折腾了两天,发现我们的项目用了反射加载配置、动态代理,AOT 编译直接报错。
不是 Spring Boot 3 的问题,是我们代码写得太"灵活"了。GraalVM 需要显式配置反射列表,动态代理的类也要提前声明。对于一个老项目来说,改造成本太高,最后放弃了。
** 总结**
升级不是改个版本号那么简单。Spring Boot 3.2 确实有很多改进(虚拟线程支持、Observability 增强),但迁移成本取决于你的项目"历史包袱"有多重。
我的建议是:先在新模块试用,别直接全量升级。如果必须升级,做好一周填坑的心理准备。
你们公司升级到 Spring Boot 3 了吗?遇到了哪些坑?我查到的资料大部分只讲新特性,实际迁移的坑很少人写。
