Spring Boot 3 之SpringBoot低版本升级最佳实践

  • 0x01 前言
  • 0x02 升级Spring Boot
  • 2.1 从Spring Boot 1.5.x 升级到Spring Boot 2.x
  • 2.1.1 依赖检查
  • 2.1.2 检查自定义配置
  • 2.1.3 检查系统需要
  • 2.1.4 升级到Spring Boot 2.x
  • 2.1.5 配置属性迁移
  • 2.2 从Spring Boot 2.7.x 升级到Spring Boot 3.0.x
  • 2.2.1 依赖检查
  • 2.2.2 Spring Security 重大升级
  • 2.2.3 检查系统需要
  • 2.2.4 查看 Spring Boot 2.x 的弃用
  • 2.2.5 配置属性迁移
  • 2.2.6 升级到 Spring Framework 6.x
  • 2.2.7 核心改变
  • 2.2.7.1 图片Banner不再支持
  • 2.2.7.2 日期格式输出
  • 2.2.7.3 类级别不再需要@ConstructingBinding
  • 2.2.7.4 YamlJsonParser 已经被移除
  • 2.2.7.5 自动配置文件
  • 2.2.8 web 应用程序变化
  • 2.2.8.1 Spring MVC 和WebFlux URL匹配变化
  • 2.2.8.2 server.max-http-header-size
  • 2.2.8.3 Jetty
  • 2.2.8.4 Actuator 健康检查变化
  • 2.2.8.5 数据访问层变化
  • 2.2.8.6 其他移除


0x01 前言

这篇博文来分享下Spring Boot 低版本升级到Spring Boot 3 的最佳实践。

0x02 升级Spring Boot

2.1 从Spring Boot 1.5.x 升级到Spring Boot 2.x

如果你是从Spring Boot 1.x 版本升级到SpringBoot 2.x,那么需要先升级到1.5.x 版本确定没问题后再开始操作。

2.1.1 依赖检查

我们需要自己查看和评估 Spring Boot 1.5.x 的依赖和Spring Boot 2.0.x 版本的依赖变化对自身项目的影响。

2.1.2 检查自定义配置

如果项目中有一些自定义的Java Config 类配置,而不是依赖自动配置机制,那么则需要关注下升级后自定义配置类是否兼容。

2.1.3 检查系统需要

  • Spring Boot 1.5.x 之前支持JDK 6 和JDK 7
  • Spring Boot 2.0.x 需要Java 8 或更高版本以及Spring Framework 5, 并且 JDK 6 和JDK7 不再支持。

2.1.4 升级到Spring Boot 2.x

  • 不建议升级到Spring Boot 2.0.0.RELEASE ,因为这个版本发现了很多问题,更新的版本已经修复了。
  • 另外,建议分阶段升级,而不是一次性升级到最新的GA 正式发布版本
  • 比如先升级到2.0.x ,然后再升级到2.1.x ,依此类推。

2.1.5 配置属性迁移

  • 在 Spring Boot 2.0 中,许多配置属性被重命名/删除,开发人员需要相应地更新他们的 application.properties/application.yml
  • 为了帮助您解决这个问题,Spring Boot 提供了一个新的 spring-boot-properties-migrator 模块。 一旦添加为项目的依赖项,这不仅会在启动时分析应用程序的环境并打印诊断信息,还会在运行时为您临时迁移属性。 这是您的应用程序迁移过程中必须具备的:

Maven版本

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-properties-migrator</artifactId>
	<scope>runtime</scope>
</dependency>

Gradle版本

runtime("org.springframework.boot:spring-boot-properties-migrator")

切记:完成迁移后,请确保从项目的依赖项中删除这个依赖。

2.2 从Spring Boot 2.7.x 升级到Spring Boot 3.0.x

如果想将自己项目的Spirng Boot 2.x 升级到SpringBoot 3.x,那么建议先升级到2.7.x 版本确定没问题后再继续操作。

2.2.1 依赖检查

我们需要自己查看和评估 Spring Boot 2.7.x 的依赖和Spring Boot 3.0.x 版本的依赖变化对自身项目的影响。

2.2.2 Spring Security 重大升级

  • Spring Boot 3.0 使用了 Spring Security 6.0。
  • Spring Security 团队发布了 Spring Security 5.8 以简化向 Spring Security 6.0 的升级。
  • 在升级到 Spring Boot 3.0 之前,请考虑将您的 Spring Boot 2.7 应用程序升级到 Spring Security 5.8。
  • Spring Security 团队已经制作了一份迁移指南,可以帮助我们这样做。

https://docs.spring.io/spring-security/reference/5.8/migration/index.html

2.2.3 检查系统需要

Spring Boot 3.0.x 需要Java 17 或更高版本以及Spring Framework 6,JDK8 不再支持。

2.2.4 查看 Spring Boot 2.x 的弃用

Spring Boot 2.x 中弃用的类、方法和属性已在此版本中删除。 请确保在升级之前没有调用已弃用的方法。

2.2.5 配置属性迁移

在 Spring Boot 3.0 中,一些配置属性被重命名/删除,开发人员需要相应地更新他们的 application.properties/application.yml。

为了帮助我们,Spring Boot 提供了一个 spring-boot-properties-migrator 模块。

一旦添加为项目的依赖项,这不仅会在启动时分析应用程序的环境并打印诊断信息,还会在运行时为您临时迁移属性。

  • Maven版本
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-properties-migrator</artifactId>
	<scope>runtime</scope>
</dependency>
  • Gradle版本
runtime("org.springframework.boot:spring-boot-properties-migrator")

切记:完成迁移后,请确保从项目的依赖项中删除这个依赖。

2.2.6 升级到 Spring Framework 6.x

Spring 版本升级到 Spring Framework 6.x

Spring Boot 3.x 依赖 Jakarta EE 规范

Spring Boot 3.0 已升级到 Jakarta EE 10 中包含的版本。

例如,Spring Boot 3.0 使用 Servlet 6.0 和 JPA 3.1 规范。

如果您正在管理自己的依赖项,而不依赖于我们的入门 POM,则应确保已适当更新 Maven 或 Gradle 文件。 您需要特别注意旧的 Java EE 依赖项不再直接或可传递地用于您的构建中。 例如,如果您应该始终使用

jakarta.servlet:jakarta.servlet-api

而不是

javax.servlet:javax.servlet-api

2.2.7 核心改变

Spring Boot 3.x 中Spring Boot 核心的一些东西也发生了很大变化。

2.2.7.1 图片Banner不再支持
  • Spring Boot 启动时候 Banner ,已不再支持图片这种类型。

banner.gif、banner.jpg 和 banner.png 文件现在将被忽略,应替换为基于文本的 banner.txt 文件。

2.2.7.2 日期格式输出
  • LogbackLog4j2 日志消息的日期和时间组件的默认格式已更改以符合 ISO-8601 标准。
  • 新的默认格式 yyyy-MM-dd'T'HH:mm:ss.SSSXXX 使用 T 代替空格字符分隔日期和时间,并在末尾添加时区偏移量。
  • LOG_DATEFORMAT_PATTERN 环境变量或 logging.pattern.dateformat 属性可用于恢复以前的默认值 yyyy-MM-dd HH:mm:ss.SSS
2.2.7.3 类级别不再需要@ConstructingBinding

@ConfigurationProperties 类的类型级别不再需要@ConstructorBinding,应该将其删除。

当一个类或记录有多个构造函数时,它仍然可以用在构造函数上以指示应该使用哪个构造函数进行属性绑定。

2.2.7.4 YamlJsonParser 已经被移除

YamlJsonParser 已被删除,因为 SnakeYAML 的 JSON 解析与其他解析器实现不一致。

如果我们直接使用的 YamlJsonParser,请迁移到其他 JsonParser 实现之一

2.2.7.5 自动配置文件

Spring Boot 2.7 介绍了一个新的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 用于注册自动配置,同时保持与 spring.factories 中注册的向后兼容性。

在Spring Boot 3.x 版本中,已删除对在 spring.factories 中注册自动配置的支持,以支持导入文件。

2.2.8 web 应用程序变化

如果我们升级的是一个web应用,那么需要好好看看这些改变。

2.2.8.1 Spring MVC 和WebFlux URL匹配变化

从 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/ 将会匹配失败返回404错误

开发人员应该改为通过代理、Servlet/web 过滤器配置显式重定向/重写,甚至在控制器处理程序上显式声明附加路由(如 @GetMapping("/some/greeting", "/some/greeting/") 更有针对性的案例。

在我们的应用程序完全适应这种变化之前,您可以使用以下全局配置更改默认值:

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
      configurer.setUseTrailingSlashMatch(true);
    }

}
2.2.8.2 server.max-http-header-size

以前,server.max-http-header-size 在四个受支持的嵌入式 Web 服务器中的处理方式不一致。

  • 使用 Jetty、Netty 或 Undertow 时,它将配置最大 HTTP 请求标头大小。
  • 使用 Tomcat 时,它会配置最大 HTTP 请求和响应标头大小。

为了解决这种不一致,已弃用 server.max-http-header-size 并引入了替代品 server.max-http-request-header-size

这两个属性现在仅适用于请求标头大小,与底层 Web 服务器无关。

要限制 Tomcat 或 Jetty(仅有的两个支持此类设置的服务器)上 HTTP 响应的最大标头大小,请使用 WebServerFactoryCustomizer

2.2.8.3 Jetty

Jetty 不再支持Servlet 6.

要在Spring Boot 3.x 中使用Jetty,需要下载servlet API 更新到5.0

我们也可以使用jakarta-servlet.version

2.2.8.4 Actuator 健康检查变化

如果项目中用了actuator 依赖,则需要关注如下变化。

  • JMX Endpoint Exposure
  • 默认情况下,现在只有健康端点通过 JMX 公开,以与默认的 Web 端点公开保持一致。
  • 这可以通过配置 management.endpoints.jmx.exposure.includemanagement.endpoints.jmx.exposure.exclude 属性来改变。
  • httptrace端点重命名为 httpexchanges
  • httptrace 端点和相关基础设施记录并提供对最近 HTTP 请求-响应交换信息的访问。
  • 在引入对 Micrometer Tracing 的支持后,名称 httptrace 可能会引起混淆。
  • 为了减少这种可能的混淆,端点已重命名为 httpexchanges
  • 端点响应的内容也受到此重命名的影响。
  • 相关的基础设施类也已重命名。 例如,HttpTraceRepository 现在被命名为 HttpExchangeRepository 并且可以在 org.springframework.boot.actuate.web.exchanges 包中找到
  • Actuator JSON
  • Spring Boot 附带的执行器端点的响应现在使用隔离的 ObjectMapper 实例来确保结果一致。
  • 如果您想恢复到旧行为并使用应用程序 ObjectMapper,您可以将 management.endpoints.jackson.isolated-object-mapper 设置为 false
  • 如果您开发了自己的端点,您可能希望确保响应实现 OperationResponseBody 接口。
  • 这将确保在将响应序列化为 JSON 时考虑隔离的 ObjectMapper
  • Acutator 端点敏感值
  • 由于 /env 和 /configprops 端点可以包含敏感值,因此默认情况下始终屏蔽所有值。
  • 这曾经只适用于被认为是敏感的密钥。
  • 相反,此版本选择了更安全的默认设置。
  • 基于键的方法已被删除,取而代之的是基于角色的方法,类似于健康端点详细信息。
  • 是否显示未过滤的值可以使用属性 management.endpoint.env.show-valuesmanagement.endpoint.configprops.show-values 进行配置,它们可以具有以下值:
  • NEVER - 所有值都经过清理(默认值)。
  • ALWAYS - 所有值都出现在输出中(将应用清理功能)。
  • WHEN_AUTHORIZED - 仅当用户获得授权时,值才会出现在输出中(将应用清理功能)。
  • 对于 JMX,用户始终被视为已授权。 对于 HTTP,如果用户通过身份验证并具有指定的角色,则认为他们已获得授权。
  • QuartzEndpoint 的清理也可以使用属性 management.endpoint.quartz.show-values 以相同的方式配置。
2.2.8.5 数据访问层变化
  • Hibernate 6.1 变化
  • Spring Boot 3.0 默认使用 Hibernate 6.1。
  • 请参阅 Hibernate 6.0 和 6.1 迁移指南以了解这对您的应用程序有何影响。
  • 依赖管理和 spring-boot-starter-data-jpa starter 已更新为使用新的 org.hibernate.orm 组 ID 作为其 Hibernate 依赖项。
  • spring.jpa.hibernate.use-new-id-generator-mappings 配置属性已被删除,因为 Hibernate 不再支持切换回旧的 ID 生成器映射。
2.2.8.6 其他移除

Spring Boot 3.0 中删除了对以下依赖项的支持:

  • Apache ActiveMQ
  • Atomikos
  • EhCache 2
  • Hazelcast 3

已删除对 Apache Solr 的支持,因为其基于 Jetty 的客户端 Http2SolrClientJetty 11 不兼容。