SpringBoot3.x升级调研报告
SpringBoot3.x升级调研报告
Before you start the upgrade, make sure to upgrade to the latest available
2.7.xversion. This will make sure that you are building against the most recent dependencies of that line.
官方提示,升级3.0前,建议先升级到2.x的最新版本进行依赖兼容性测试,确保升级3.x顺利。截至当前为止,最新的2.x版本为v2.7.17
总结
- SpringBoot3版本自2022年发布第一个release版本以来,经过近两年时间的调整迭代已经逐渐完善各种支持,虽然从发版的chagelog看仍有较多的bug在不断的修复当中,但是已经具备稳定开发的条件。目前最新的发行版为:
v3.2.4。 - 从整体的调研结果看,由于目前国内大量的项目仍采用SpringBoot2版本进行开发,而2到3的升级出现较多的破坏性升级,如大量依赖变更、部分功能调整、删除,自动配置功能调整导致大量三方starter失效等,这是需要较多的人力和回归测试来保障升级安全的,这是升级阻碍比较明确的一个问题。
- 从目前的调研结果看,开发常用的三方starter经过两年的发展基本上都提供了兼容SpringBoot3的版本,这也为切换到SpringBoot3提供了有力的支撑,意味着庞大的开源社区已经逐渐切换到SpringBoot3的生态了。
- 运行环境问题。在SpringBoot3中,最低要求
Java17的版本,众所周知的原因,Oracle提供的JDK发行版在Java8后逐渐转向商业收费,这个原来是阻碍升级非常重要的一个因素,但是经过几年的发展,已经出现较多的免费商用的OpenJDK发行版足以解决该问题,如Eclipse管理的AdoptOpenJDK就是目前非常流行的一个。 - 支持SpringBoot3的cloud版本已经发布,这意味着依赖cloud提供分布式治理能力的其它框架也可以方便进行接入了。
- 在不考虑使用Graalvm特性的前提下,升级到SpringBoot3的条件已经基本成熟。
运行环境
Java运行环境
最低要求Java 17
Spring Framework环境
要求6.0版本
依赖变动
升级后,存在大量的依赖变更情况,统计结果如下(统计数据来源:官方依赖说明):
新增: 236
删除: 179
变更: 1562
更具体的依赖差异细节请查阅:依赖差异详情
风险点
1. 依赖兼容问题
本次升级依赖变更较大,从统计结果分析,基本上整体依赖都进行了版本变更或者删除,特别是删除的部分依赖中,有比较多的依赖是较常用的,例如javax系列的扩展包,这可能会导致很多三方模块无法正常使用。
解决方案: 建议开发工具针对依赖进行遍历检查,如利用maven的依赖树,对于被删除的依赖要及时识别出来。其次针对变更的依赖,需要对业务进行回归测试,暂时没有更好的方式识别可能存在的不兼容问题。或者考虑人工测试检查依赖的兼容情况。
2. Java版本付费问题
根据Oracle 免费条款和条件 (NFTC) 要求,JDK17及后续版本需要遵守非商用约定,要注意风险。
由于要求最低版本是17,如果进行升级就需要考虑Java版本付费的问题。
解决方案: 使用AdoptOpenJDK等其它发行版的JDK
AdoptOpenJDK 目前由Eclipse基金会维护,采用GNU General Public License, version 2 with the Classpath Exception开源协议发布,可以免费用于商业环境。


3. 过期被清理的类、方法和属性
在2.x版本中被标记为过期的类、方法和属性在本次破坏性升级中已经被移除,所有依赖这些过期功能的三方模块、业务功能将无法正常运作。
解决方案: 针对业务代码,升级后被清理的功能会导致相关源码报错无法编译,由开发人员识别并处理即可。针对第三方模块,建议优先升级到已经保证兼容SpringBoot3的版本,如果没有兼容版本,则可能需要对使用到相关模块的业务代码进行功能测试。
4. 配置变更
在 Spring Boot 3.0 中,一些配置属性被重命名/删除,开发人员需要相应地更新业务代码中的application.properties/application.yml 。Spring Boot 官方提供了 spring-boot-properties-migrator 模块。 作为依赖项添加到项目中,会在启动时分析应用程序的环境并打印诊断信息,还会在运行时临时迁移属性,保证旧配置的兼容。
解决方案: 引入spring-boot-properties-migrator模块配合变更配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
5. 较多的破坏性功能升级
本次升级出现较多的破坏性升级,不再对2.x的规范进行兼容处理。因此导致了即便解决了JDK的问题,也无法直接从2.x升级到3.x,否则会出现业务无法正常运行的问题。
解决方案: 根据官方给出的升级细节以及解决方案,检查业务是否需要变更。部分变更兼容可以由平台统一升级,其它部分由开发者自行处理。
破坏性升级
1. SpringSecurity
Spring Boot 3.0 使用 Spring Security 6.0。Spring Security 团队发布了 Spring Security 5.8,以简化升级到 Spring Security 6.0 的过程。升级指南
解决方案: 主要更新内容是密码编码器相关的使用要求,如果没有使用SpringSecurity或者没有变更默认的密码编码器则可以跳过处理。
升级到5.8版本确认功能通过测试后再准备升级6.0
2. Banner
不再支持gif jpg png格式的banner文件,只能使用基于文本的banner
解决方案: 更换为文本的banner
3. 默认日志输出格式的时间格式变更
默认的时间格式由yyyy-MM-dd HH:mm:ss.SSS 变更为 yyyy-MM-dd’T’HH:mm:ss.SSSXXX。这可能会影响部分使用了默认日志输出格式的日志采集方案的正常运行。
解决方案: 调整日志采集格式或者通过配置logging.pattern.dateformat参数修改为之前的时间格式
4. @ConstructingBinding不再需要使用
@ConstructingBinding注解不再需要在配置类中使用,应该移除(除非有多个构造函数的情况下使用该注解声明应该使用哪个构造函数初始化配置)。
解决方案: 业务上很少出现这种用法,根据说明调整即可。
5. YamlJsonParser解释器被移除
该解析器用于解析yaml格式,如果业务代码中有使用到的需要变更为其它实现方式。
解决方案: 业务上很少出现这种用法,根据说明调整即可。
6. Auto-Configuration机制变更
在3.x版本使用了新的自动配置装配文件:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports。2.x的方式已经不再可用,这个变更会影响大量的现有的模块,导致其无法正常运行 。
解决方案:
- 使用独立的兼容模块为2.x的模块编写新的自动装配文件。
- 升级对应模块到3.x的版本
7. 尾部斜杠匹配默认值变更
从 Spring Framework 6.0 开始,尾部斜杠匹配配置选项已被弃用,其默认值设置为 false。 这意味着以前,以下控制器将匹配“GET /some/greeting”和“GET /some/greeting/”:
@RestController
public class MyController {
@GetMapping("/some/greeting")
public String greeting() {
return "Hello";
}
}
默认情况下,“GET /some/greeting/”不再匹配,并返回HTTP 404 错误。
解决方案:
- 修改path,如果确实需要匹配尾部斜杠的,可以修改为:
@GetMapping("/some/greeting", "/some/greeting/") - 重新修改默认配置,匹配尾部斜杠
webmvc
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch(true);
}
}
webflux
@Configuration
public class WebConfiguration implements WebFluxConfigurer {
@Override
public void configurePathMatching(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch(true);
}
}
8. server.max-http-header-size配置弃用
该配置在2.x版本中表现不一致,在tomcat容器中可以同时设置最大请求标头和最大响应标头,在jetty、netty、undertow中只能设置最大请求标头,因此为了统一效果已经弃用该配置,改为通过:server.max-http-request-header-size设置最大请求标头。
9. 优雅关机机制变更
通过SmartLifecycle接口实现优雅关机的机制变更,新的优雅关机阶段位于:SmartLifecycle.DEFAULT_PHASE - 2048。web容器停止的阶段位于:SmartLifecycle.DEFAULT_PHASE - 1024。该变更主要影响平台级能力,特别是实现了优雅关机能力的模块。
解决方案: 重新调整优雅关机的适配阶段
10. Servlet标准支持
SpringBoot3.x默认使用servlet6.0的标准,由于部分web容器并未支持该标准,需要开发者进行处理(目前Jetty容器不支持)。
解决方案:
- 改用其它web容器
- 降级servlet标准到5.0。即:加入配置项:
jakarta-servlet.version=5.0
11. RestTemplate不再支持HttpClient
SpringBoot3.x不再提供对HttpClient的支持,如果平台模块或者业务代码使用了旧版本的HttpClient可能会导致RestTemplate运行异常,需要变更为HttpClient5。
解决方案:
- 将所有的依赖(包括间接依赖)引入的HttpClient(
org.apache.httpcomponents:httpclient)依赖移除,并引入HttpClient5的依赖(org.apache.httpcomponents.client5:httpclient5)。
12. Spring Boot Actuator变动
解决方案:
根据官方说明调整即可
13. 监控指标调整
在新版本上,与Micrometer 1.1进行了集成,使用方式进行了变更,导致不仅限于:WebMvcMetricsFilter ServerHttpObservationFilter MetricsRestTemplateCustomizer 等内置实现被移除。这对部分使用了相关功能的应用是有影响的,可能出现编译失败、运行异常等问题。
解决方案:
根据官方说明调整即可。调整内容
14. Spring Data变更
SpringData模块存在部分配置调整、依赖变更、使用方式调整。包括:Cassandra redis flyway liquibase hibernate mongodb r2dbc elasticsearch
解决方案:
对比项目中是否使用了相关的功能,根据官方说明调整即可。调整内容
15. Spring Batch变更
Spring Batch模块升级到Spring Batch5.0,涉及了较多的更改内容:Spring Batch升级说明,对使用该功能进行批量任务处理的项目影响较大,应该谨慎评估升级。在SpringBoot3方面,Spring Batch也存在以下变动:1. @EnableBatchProcessing现在不是必须的,除非需要明确声明关闭自动配置,否则应该移除该注解 2. 启动时默认不再支持自动运行多个job,如果有多个job需要通过配置:spring.batch.job.name明确声明
解决方案:
对比项目中是否使用了相关的功能,根据官方说明调整即可。
16. Spring Session变更
不再支持通过配置:spring.session.store-type指定存储类型。对于部分项目可能会有影响,如使用redis作为分布式会话管理。相应的,新版本通过固定顺序的方式自行选择合适的会话存储。顺序参考如下:
- Redis
- JDBC
- Hazelcast
- MongoDB
解决方案:
参考官方说明调整。调整内容。
常用开发组件兼容性
Jakarta EE
SpringBoot3.0将原来的JavaEE标准升级为Jakarta EE,因此如果项目中使用了旧标准的导入需要重新处理。具体就是将javax.servlet依赖变更为:jakarta.servlet-api,同时受影响的还包括其它使用了旧标准的第三方模块,也应该同步升级。
解决方案: 根据官方的建议,提供了几个有助于迁移的工程
Mybatis Plus
mybatis plus开源社区已提供3.0的支持版本,需要更换依赖进行升级
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>Latest Version</version>
</dependency>
目前为止最新的版本是:v3.5.5
注意,由于3.0移除了mybatis-plus使用的NestedIOException类,所以如果项目使用了mybaits plus,则无法简单通过修复自动装配类的方式兼容旧版本的mybatis plus,需要升级3.0的专用版本
SpringCloud
支持SpringBoot3的cloud版本已经发布:2022.0.0 目前最新的release版本为:2022.0.0-M4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2022.0.0-M4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Jasypt
常用的配置加解密模块。目前已发布兼容springboot3的版本
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
RocketMQ
常用的消息中间件,已发布兼容springboot3的版本
<!--add dependency in pom.xml-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
Redis
常用的缓存中间件。SpringBoot官方支持
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>