Dante Cloud 升级 Spring Boot 4 经验分享

代码重构艺术 3.6w人浏览 40人参与

Java 开源圈 2025 年最引人注目的事情之一,莫过于 Spring Framework 7 和 Spring Boot 4 的发布。Dante Cloud 微服务云原生基座项目核心定位之一,就是“极尽努力与 Spring 生态的标准规范保持一致”,所以也同步开启了 适配 Spring Boot 4.X 的 Dante Cloud v4 版本的开发工作。

从 Spring Boot 4 第一个正式版本发布至今也有一个月了,Dante Cloud v4 版本也同步发布了 5 个 milestone 版本,在这个过程也积累了一些升级 Spring Boot 4 的经验,在 Spring Boot 4.0.1 发布之际,与大家分享,希望大家在后续的升级过程中尽量必坑。

介绍 Spring Framework 7 和 Spring Boot 4 新特性的文章已经非常多了,本文是从实战角度出发,结合自己的实际升级经验,对目前升级 Spring Boot 4 进行一个阶段总结。

一、 “免责声明”

说是“免责声明”其实是开玩笑,其实主要是一些注意事项:

因为每个人的项目规模以及对 Spring Boot 使用深入度的不同,在升级 Spring Boot 4 时的工作量可大可小。

例如:

  • 你的项目完全是可以脱离 Spring 环境独立使用的组件,仅是定义了一个 Starter 方便 Spring Boot 环境使用,那么升级 Spring Boot 4 的工作量会非常小。
  • 你的项目深度使用 Spring Boot,Spring Boot 特性用得的非常多,主要使用 Spring Boot 推荐的技术开发,甚至是多模块共享的多工程环境,那么工作量一定不小。

所以,升级 Spring Boot 4 之前,还是要结合自己的实际情况,具体分析判断。学会举一反三,切勿盲从。

二、 New Moduler Design

虽然说 Spring Framework 7 和 Spring Boot 4 新特性很多,但是代码管理以及兼容性做得非常好,对于使用者来说基本是“无感知”的。对现有代码影响微乎其微,想使用就用不想使用就不用

“New Moduler Design” 这一项对于开发者使用的影响确实最直接的,也是个人认为升级 Spring Boot 4 工作量最大的一项。

1. 为什么要重新设计模块?

长久以来,Spring Boot 一直会收到诟病的点,就是启动性能方面不理想。Spring Boot 的核心模块 spring-boot-autoconfigure 是影响启动性能重要因素之一(当然还有其它因素以及其它 autoconfigure 类型的模块影响)。

随着 Spring Boot 的不断发展,集成的相关组件或技术就越来越多。每一项组件或技术的集成,都需要实现相关的自动配置以便实现各种技术的“可插拔”,而这些配置代码都放置在spring-boot-autoconfigure

这样做的好处就是:

  • 放在同一个模块好管理好维护。
  • 可以更加方便的控制各种配置类和 Bean 的注入先后顺序。

这样做的坏处就是:

  • Spring Boot 应用启动时,需要扫描所有的配置类和 Bean,分析其中启动顺序以及生效的条件等。Spring Boot 支持的内容越多,spring-boot-autoconfigure 就越臃肿,那么启动时需要分析的内容就越多,就会影响启动的性能
  • spring-boot-autoconfigure 中的内容,不管你实际项目中是否用到,启动时都是需要进行分析和条件判断。

因此,Spring Boot 4 最大变化之一,就是将 spring-boot-autoconfigure 中的内容,拆分成各自独立的模块。拆分出来的模块,统一以 spring-boot-<technology> 格式进行命名。

例如:原本 WebClient 的默认配置代码是放置在 spring-boot-autoconfigure 模块中,被拆分出来之后,WebClient 默认的配置代码就被放置到 spring-boot-webclient 模块中

在实际开发中就不要统一依赖 spring-boot-autoconfigure,根据需要用到那种技术就手动依赖相关的 spring-boot-<technology> 模块或者对应的 Starter。

这样可以极大地减少启动时配置类的扫描和分析,以达到提升性能的目的

2. 拆分后如何控制配置注入顺序?

这个问题其实是 spring-boot-autoconfigure代码拆分后的最大问题,为了解决这个问题 Spring Boot 在 @AutoConfiguration 中新增两个属性:aftername beforename。通过这两个属性,你可以直接以“字符串”形式配置其它模块某个配置类的完整类路径。

这样就不用再通过依赖模块,配置具体 Class 的方式控制配置顺序,而且解决了跨模块控制配置类顺序的问题

3. 为什么升级工作量大?

工作量大不大,请结合“免责声明”章节内容,还是要结合项目实际情况而定,切勿无脑抬杠。

Spring Boot 4 “New Moduler Design”带来了性能的提升,同时也给升级带来了最大阻碍。

原本所有代码都是放置在 spring-boot-autoconfigure中,工程中默认就依赖了。不管是你自己的配置类中自动注入相关的配置,还是代码中用到了其中的代码都非常方便。

Spring Boot 4 将spring-boot-autoconfigure中的代码拆分为不同模块之后,其中还会涉及到类路径的变化。

如果你的代码用到了很多spring-boot-autoconfigure中的代码,那么在升级 Spring Boot 4 时,不仅要找打原有代码所在的新模块,还要去找对应的类在新模块中所在的包。因为没有统一的可以索引的地方,只能自己慢慢地找。

作者是直接将 Sping Boot 的源码下载下来,找不到代码时就在 Spring Boot 源码中全文搜索。

4. 带来的启示

原本 Spring Boot 2.X 升级 3.X 时,除了一些特性的变化外,整体的代码结构和包路径还是基本保持一致,这种情况下还可以考虑一下兼容问题。

因为,Spring Boot 4 中会出现很多类的包路径变化的情况,这样就很难考虑兼容的问题。(类路径都变了,考虑兼容还有什么意义)

所以,如果你的项目原本需要考虑兼容性的,升级 Spring Boot 4 时就别考虑兼容问题了,都是无用功。

三、 周边生态的适配

升级 Spring Boot 4 另一项重要工作,就是你所使用到的周边第三方组件的适配。之所以说这项工作重要,原因其实在前面的内容中已经说到了,就是:Spring Boot 4 中很多类的包路径变了,这是没有什么好办法进行兼容处理的,只有等者周边生态软件的适配。

如果不适配会直接影响代码运行的

以 Dante Cloud 项目为例,需要等待适配的周边,以及相关的进度如下:

  • Spring Cloud Alibaba:已经有 Committer 提交了适配代码,因为项目在考虑彻底删除对 Bootstrap 模式的支持,所以还没有发测试或者正式版本
  • Spring Cloud Tencent:项目团队人员少,在等着社区 Committer 贡献适配代码
  • Spring Boot Admin:正在适配中
  • Resilience4j:还没有看到相关计划
  • Jasypt Spring Boot Starter:时隔几年才刚发布适配 Spring Boot 3.5 版本,适配 Spring Boot 4 还得等

四、 Jackson3

Spring Boot 4 中另一项比较有影响的变化就是开始使用 Jackson 3。

Jackson 3 主要的变化有:

  1. com.fasterxml.jackson 变为 tools.jackson。所以,如果你深度使用 Jackson 还想用 Jackson3,那么会大量修改包路径的工作
  2. new ObjectMapper 已经不推荐使用。需要使用以下方式创建:
this.objectMapper = JsonMapper.builder()
        .enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)
        .enable(JsonReadFeature.ALLOW_SINGLE_QUOTES)
        .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
        .build();
  1. 注解相关配置方式变化
JsonMapper.builder()
        .changeDefaultPropertyInclusion(incl -> incl.withValueInclusion(JsonInclude.Include.NON_NULL))
        .build();
  1. 部分原有需要手动关闭的配置,目前 Jackson3 已经修改默认关闭
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
  1. Jackson3 所有方法统一抛出 JacksonException

注意事项

  1. jackson3 中,还是使用的 jackson 2.x annotation 模块,所以如果使用了 jackson 注解,注解的坐标还是com.fasterxml.jackson,所以在修改 jackson 3 包名时,如果想用 IDE 进行全局包路径替换一定要谨慎,以防改错。
  2. Spring Boot 4 还保留了 Jackson 2 的支持。Jackson 2 的代码均放置在 **.Jackson2.** 包下面,而 Jackson 3 的代码均放置在 **.Jackson.** 包下面

五、 commons-lang3

Spring Boot 4 基础依赖的 commons lang3 已经升级至 3.19.0。

自 commons lang3 3.18.0 版本起,String 相关操作工具类有了较大变化,原有 StringUtils.XX,拆分为 Strings.CI.XX Strings.CS.XX

因此,还会涉及大量包路径的修改

升级至 3.19.0,原有方法 StringUtils.XX 仍然可用,不过又有大量过时告警。

六、 JSpecify

Spring Boot 4 中,全面引入 JSpecify 相关注解进行空值标注。

所以建议将原有 Spring 提供的 Nullable 以及 IDEA 提供的 NotNull 注解全部替换为 JSpecify。

注意:如果你实现或者扩展了 Spring 或者相关组件的一些方法,建议检查一下是否已经变换为 JSpecify 注解。如果变换了建议将自己的实现方法同步修改一下

七、 API 版本

Spring Boot 4 中最吸引人的另一个功能,莫过于对于 API 版本的支持。Dante Cloud 也同步增加了对 API 版本动态鉴权的支持。

Spring Boot 4 API 版本,支持 Query 参数版本、路径版本、以及请求 Header 版本三种,获取版本方式。需要结合自己的实际进行修改。

如果你想支持 API 版本,同时支持 API 接口的动态鉴权,那么会有一定的工作量

八、 Undertow 移除

Undertow 作为一款高性能的 Web 容器,深受用户喜爱。但是因为对 Servlet 6.1 支持度较差,不符合 Spring Boot 的发展方向,所以在 Spring Boot 4 中已经将 Undertow 相关的支持移除。

因为 Dante Cloud 一直以来都在使用 Undertow 作为 Web 容器,所以不得不在新版本中进行更换。最早是更为换 Tomcat,但是 Tomcat 过于厚重、性能优化配置繁琐、启动速度明显慢,所以最终还是更换为更加轻量的 Jetty。

总结

整体而言,升级 Spring Framework 7 和 Spring Boot 4 机制方面的变化,对于用户来说是“无感的”。Dante Cloud 升级 Spring Boot 4 的工作,其实大量的工作都是在修改“包路径”。

升级 Spring Boot 3.X 时,大部分人还抱着“怀疑”、“观望”的态度。但是到了 Spring Boot 4.X,很多开源社区在正式版未发布之前就已经开始着手适配工作。可见其对于用户吸引力有多打。

Spring Boot 4 机制以及对性能的提升,特别是对 JDK 25 的支持,非常值得一试。 目前升级 Spring Boot 4 最大的难点就在于周边生态的适配度。


项目地址:

Giteehttps://gitee.com/dromara/dante-cloud

Githubhttps://github.com/dromara/dante-cloud

Gitcodehttps://gitcode.com/dromara/dante-cloud

Spring Boot 的约定大于配置理念使 Spring 使用更便捷,Spring Boot 项目组提供了很多 Starter,官方 Starter 采用 spring-boot-starter-xxx 开头,非官方的建议采用 xxxx-spring-boot-starter 命名,短信服务 Starter 也是其中之一 [^1]。 ### 使用指南 1. **引入依赖**:在 pom 文件中引入如下依赖: ```xml <dependency> <groupId>com.github.jackieonway.sms</groupId> <artifactId>sms-spring-boot-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> ``` [^4] 2. **启用方式**: - **主动生效**:在 starter 组件集成入 Spring Boot 应用时需要主动声明启用该 starter 才生效。使用 `@Import` 注解,将该注解标记到自定义的 `@Enable` 注解上,标记到 Spring Boot 应用就可以使用短信功能 [^2]。 - **被动生效**:在 starter 组件集成入 Spring Boot 应用时就会被应用捕捉到。在 autoconfigure 资源包下新建 `META-INF/spring.factories` 写入 `SmsAutoConfiguration` 全限定名,多个配置类逗号隔开,换行使用反斜杠 [^2]。 3. **自动装配配置**:对于 simple-sms-spring-boot-starter,在 resources 文件夹下创建 `META-INF` 目录,定义 `spring.Factories` 文本文件,写入 key 为 `org.springframework.boot.autoconfigure.EnableAutoConfiguration`,value 为定义的配置类全限定名,如 `org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xll.config.SmsAutoConfiguration`,之后将 starter 打成 jar 包放入本地仓库 [^5]。 ### 功能介绍 以 Dante Cloud 的 sms-spring-boot-starter 为例,它提供了一个完整、安全、高效的消息服务解决方案,具体功能如下: - **快速集成**:通过简单的依赖配置就能快速集成消息服务。 - **灵活配置**:支持多环境、多厂商的灵活配置。 - **安全可靠**:内置安全检测和频率限制机制。 - **监控完善**:提供完整的监控和日志记录能力。 - **易于扩展**:支持自定义消息服务提供商集成 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码匠君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值