1. 关键要点
- 为什么你应该升级你的服务
- 迁移到 Spring Boot 3.3 时需要更新的内容
- OpenRewrite 如何帮助使升级更轻松、更快捷
2. 前言
现在Spring Boot 已经到了3.3,但是你在哪里?在过去的 3.x 版本更新中,我们看到了许多新功能,包括使用新的 Java
语言功能的能力、增强的可观察性、更好地支持使用 Graal 进行本机编译以及对虚拟线程的支持。
然而,对于许多人来说,升级到最新版本似乎非常困难,尤其是从旧 2.x 版本升级而来的人。毕竟,除了 Spring 之外,还有很多东西需要更新,例如 Java 版本和迁移到 Jakarta EE 9。而且您的组织中可能运行着各种依赖项的许多不同版本,这使得迁移任务更加困难。
继续阅读以了解如何使整个组织的软件迁移过程更加顺畅。
3. 为什么你应该升级你的服务
人们很容易采取“如果没有损坏,为什么要修复它”的想法。但是,OSS 对 Spring Boot 2.x 的支持已于 2023 年11 月结束。
这意味着您需要进行所有这些升级,以确保在发布新的 CVE 时您的软件保持安全。此外,通过升级,您将可以访问许多工具中的大量新功能。
例如,通过升级到 Java 17(这是 Spring Boot 3.0+ 的要求),您不仅可以获得各种新的 Java 语言功能(记录、模式匹配、switch 表达式等),还可以受益于虚拟机和垃圾收集器的性能改进。
注意:您的环境将具有独特的性能足迹。最好使用监控平台来创建应用程序当前性能的基准,这样您就可以在升级时量化节省的成本。
关于 Spring Boot 3.x,您可以从对构建本机可执行文件和使用 GraalVM 的更好支持中受益。通过将 Spring 应用程序构建为本机可执行文件,您会发现启动时间有显著改善。您还会发现可观察性是此新版本中的一个关键主题,现在通过Micrometer Tracing实现跟踪。
从Spring Boot 3.2开始,您可以利用 Java 21 及更高版本中的虚拟线程。通过卸载阻塞 IO 操作,您可以从同一硬件处理更多请求,而不会使编程模型复杂化。
4. 迁移到 Spring Boot 3.x 时需要更新的内容
迁移到 Spring Boot 3.x 包括许多相关的迁移和依赖项更新,您必须在迁移到此新 Spring Boot 版本之前执行这些更新,其中包括:
- 升级您组织的应用程序、基础设施和 CI/CD 管道以使用 Java 17 或 21。此步骤的好消息是,这项工作可以在升级任何 SpringBoot 应用程序之前完成。
- 任何利用 Java EE 的现有 Spring 应用程序都需要更新到 Jakarta EE 9。这似乎是一项简单的练习,涉及将所有导入从“javax”命名空间移动到“jakarta”命名空间,但这还要求将任何第三方库也迁移到与 Jakarta EE 9 兼容的版本。
- 最后,根据应用程序从哪个 Spring Boot 版本迁移而来,迁移到 Spring Boot 3.x 时可能需要对应用程序的代码和配置进行一些更改
5. Java 17 迁移
Spring Boot/Spring 需要 Java 17 的基准版本,并且需要应用程序迁移到 Java 平台的最新长期支持 (LTS) 版本。
对于在 Java 8 上运行的应用程序,主要的摩擦来源是Java 9 中引入了模块系统,以及从核心 JDK 中删除了许多 J2EE javax 依赖项。使用任何 Java EE 规范的应用程序都需要向其项目添加显式依赖项。此外,还有许多与 Java 模块系统不兼容的第三方依赖项,必须作为此练习的一部分进行升级。
从 Java 11 开始,OpenJDK 社区采用了新的六个月发布周期,因此用户现在必须处理已弃用的 API。已弃用的功能最初不会造成严重影响,但随后会从 Java 平台中删除。跨 Java 多个版本升级的应用程序必须解决从平台中删除的 API。幸运的是,有一个 Java 工具Jdeprscan可用于识别哪些 API 已从平台弃用或删除。使用这些 API 的应用程序需要修复其解决方案才能成功升级到 Java 17。
6. Java 21 和虚拟线程
还有一个方便的Spring Boot 3.x 最佳实践配方,可让您升级到最新的 Spring Boot 3.x 版本,以及升级到 Java 21 和使用虚拟线程。今后,我们将保留此配方作为方便的配方,以便一次性应用所有推荐的 Spring Boot 配方。
作为升级到 Java 21 的一部分,我们还将采用新的 Sequenced Collections 接口中的方法,并放弃现已弃用的 Locales 和 URL 构造函数,以及其他一些较小的增强功能。有关完整详细信息,请参阅迁移到 Java 21 配方。
7. Jakarta EE 9 迁移
Spring Boot 3.x 更新之前需要处理的另一项重要任务是迁移到 J2EE 9。这很重要,因为所有 Java EE
库的命名空间都已从 javax 更改为 jakarta.*。作为其中的一部分,对这些库的任何引用都必须将其包迁移到新的命名空间。
此外,Jackson、Hibernate、Tomcat 和 Jetty 等第三方库提供了与 Jakarta EE 9 兼容的替代工件。这些新的工件将要求 Sprint Boot 的用户仔细检查他们的第三方库,以确保他们拥有兼容的工件。
8. OpenRewrite 自动重构如何提供帮助
好消息是,OpenRewrite 社区正在研究许多复杂更改的方案。这意味着这些更新的很大一部分可以使用OpenRewrite自动完成。
对于那些不知道的人来说,OpenRewrite 是一个语义感知的代码搜索和转换工具。它能够对代码、构建文件和配置进行复杂的更改,这些更改在惯用性上与现有项目的格式标准一致。
实际上,OpenRewrite 有大量的方案可以帮助用户迁移到 Spring Boot 3,其中包括:
- 从旧版本的 Java 迁移到 Java 17
- 从 Junit 4 迁移到 Junit 5
- 从 Java EE 迁移到 Jakarta EE 8 和 9
- 从旧版本的 Spring Boot 迁移(1.5 -> 2.x、2.7 ->3.0、3.0 -> 3.x)
- 这些配方会改变编码、更新和配置!
配方是可组合的,这使得更大规模的框架迁移可以包含调用一组执行特定任务的配方或将其他复合配方链接在一起。
例如,迁移到 Java 11 的配方可以利用修改 Maven 依赖项的配方和针对特定已弃用 API 迁移的配方。反过来,迁移到 Java 17 的配方可以链接到 Java 11 配方,而Spring Boot 3.x 迁移配方可以利用这些配方以及将 Jakarta EE 库迁移到版本 9 的配方。
如果您想缩小所做更改的范围,还可以利用配方的可组合特性来定位您尚未更新的特定组件。例如,如果不使用 Spring Boot 3.x,您可以:
- 将 Spring Boot 2.x 项目从 JUnit 4 迁移到 JUnit 5
- 迁移到 Spring Security 5.8
- 迁移到 Java 17
- 执行 Spring Boot 2.x 最佳实践