这篇博文来分享下Spring Boot 低版本升级到Spring Boot 3 的最佳实践。
如果你是从Spring Boot 1.x 版本升级到SpringBoot 2.x,那么需要先升级到1.5.x 版本确定没问题后再开始操作。
我们需要自己查看和评估 Spring Boot 1.5.x 的依赖和Spring Boot 2.0.x 版本的依赖变化对自身项目的影响。
- Spring Boot 1.5.x 对其他第三方开源库的依赖兼容关系
- Spring Boot 2.0.x 对其他第三方开源库的依赖兼容关系
- Spring Boot 2.1.x 对其他第三方开源库的依赖兼容关系
- Spring Boot 2.2.x 对其他第三方开源库的依赖兼容关系
- Spring Boot 2.3.x 对其他第三方开源库的依赖兼容关系
- Spring Boot 2.4.x 对其他第三方开源库的依赖兼容关系
- Spring Boot 2.5.x 对其他第三方开源库的依赖兼容关系
- Spring Boot 2.6.x 对其他第三方开源库的依赖兼容关系
- Spring Boot 2.7.x 对其他第三方开源库的依赖兼容关系
如果项目中有一些自定义的Java Config 类配置,而不是依赖自动配置机制,那么则需要关注下升级后自定义配置类是否兼容。
在 Spring Boot 2.0 中,许多配置属性被重命名/删除,开发人员需要相应地更新他们的 application.properties/application.yml
。
为了帮助您解决这个问题,Spring Boot 提供了一个新的 spring-boot-properties-migrator
模块。 一旦添加为项目的依赖项,这不仅会在启动时分析应用程序的环境并打印诊断信息,还会在运行时为您临时迁移属性。 这是您的应用程序迁移过程中必须具备的:
Maven版本
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-properties-migratorartifactId>
<scope>runtimescope>
dependency>
Gradle版本
runtime("org.springframework.boot:spring-boot-properties-migrator")
切记:完成迁移后,请确保从项目的依赖项中删除这个依赖。
如果想将自己项目的Spirng Boot 2.x 升级到SpringBoot 3.x,那么建议先升级到2.7.x 版本确定没问题后再继续操作。
我们需要自己查看和评估 Spring Boot 2.7.x 的依赖和Spring Boot 3.0.x 版本的依赖变化对自身项目的影响。
https://docs.spring.io/spring-security/reference/5.8/migration/index.html
Spring Boot 3.0.x 需要Java 17 或更高版本以及Spring Framework 6,JDK8 不再支持。
Spring Boot 2.x 中弃用的类、方法和属性已在此版本中删除。 请确保在升级之前没有调用已弃用的方法。
在 Spring Boot 3.0 中,一些配置属性被重命名/删除,开发人员需要相应地更新他们的 application.properties/application.yml。
为了帮助我们,Spring Boot 提供了一个 spring-boot-properties-migrator 模块。
一旦添加为项目的依赖项,这不仅会在启动时分析应用程序的环境并打印诊断信息,还会在运行时为您临时迁移属性。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-properties-migratorartifactId>
<scope>runtimescope>
dependency>
runtime("org.springframework.boot:spring-boot-properties-migrator")
切记:完成迁移后,请确保从项目的依赖项中删除这个依赖。
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
Spring Boot 3.x 中Spring Boot 核心的一些东西也发生了很大变化。
banner.gif、banner.jpg 和 banner.png 文件现在将被忽略,应替换为基于文本的 banner.txt 文件。
Logback
和 Log4j2
日志消息的日期和时间组件的默认格式已更改以符合 ISO-8601
标准。
新的默认格式 yyyy-MM-dd'T'HH:mm:ss.SSSXXX
使用 T 代替空格字符分隔日期和时间,并在末尾添加时区偏移量。
LOG_DATEFORMAT_PATTERN
环境变量或 logging.pattern.dateformat
属性可用于恢复以前的默认值 yyyy-MM-dd HH:mm:ss.SSS
。
在@ConfigurationProperties
类的类型级别不再需要@ConstructorBinding,应该将其删除。
当一个类或记录有多个构造函数时,它仍然可以用在构造函数上以指示应该使用哪个构造函数进行属性绑定。
YamlJsonParser
已被删除,因为 SnakeYAML
的 JSON 解析与其他解析器实现不一致。
如果我们直接使用的 YamlJsonParser
,请迁移到其他 JsonParser
实现之一
Spring Boot 2.7 介绍了一个新的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
用于注册自动配置,同时保持与 spring.factories
中注册的向后兼容性。
在Spring Boot 3.x 版本中,已删除对在 spring.factories
中注册自动配置的支持,以支持导入文件。
如果我们升级的是一个web应用,那么需要好好看看这些改变。
从 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);
}
}
以前,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
。
Jetty 不再支持Servlet 6.
要在Spring Boot 3.x 中使用Jetty,需要下载servlet API 更新到5.0
我们也可以使用jakarta-servlet.version
如果项目中用了actuator 依赖,则需要关注如下变化。
- 默认情况下,现在只有健康端点通过 JMX 公开,以与默认的 Web 端点公开保持一致。
- 这可以通过配置
management.endpoints.jmx.exposure.include
和management.endpoints.jmx.exposure.exclude
属性来改变。
httptrace
端点重命名为 httpexchanges
- httptrace 端点和相关基础设施记录并提供对最近
HTTP
请求-响应交换信息的访问。- 在引入对
Micrometer Tracing
的支持后,名称httptrace
可能会引起混淆。- 为了减少这种可能的混淆,端点已重命名为
httpexchanges
。- 端点响应的内容也受到此重命名的影响。
- 相关的基础设施类也已重命名。 例如,
HttpTraceRepository
现在被命名为HttpExchangeRepository
并且可以在org.springframework.boot.actuate.web.exchanges
包中找到
- Spring Boot 附带的执行器端点的响应现在使用隔离的
ObjectMapper
实例来确保结果一致。- 如果您想恢复到旧行为并使用应用程序 ObjectMapper,您可以将
management.endpoints.jackson.isolated-object-mapper
设置为false
。- 如果您开发了自己的端点,您可能希望确保响应实现
OperationResponseBody
接口。- 这将确保在将响应序列化为
JSON
时考虑隔离的ObjectMapper
。
由于
/env
和 /configprops 端点可以包含敏感值,因此默认情况下始终屏蔽所有值。这曾经只适用于被认为是敏感的密钥。
相反,此版本选择了更安全的默认设置。
- 基于键的方法已被删除,取而代之的是基于角色的方法,类似于健康端点详细信息。
- 是否显示未过滤的值可以使用属性
management.endpoint.env.show-values
或management.endpoint.configprops.show-values
进行配置,它们可以具有以下值:
- NEVER - 所有值都经过清理(默认值)。
- ALWAYS - 所有值都出现在输出中(将应用清理功能)。
- WHEN_AUTHORIZED - 仅当用户获得授权时,值才会出现在输出中(将应用清理功能)。
对于 JMX,用户始终被视为已授权。 对于 HTTP,如果用户通过身份验证并具有指定的角色,则认为他们已获得授权。
QuartzEndpoint 的清理也可以使用属性
management.endpoint.quartz.show-values
以相同的方式配置。
- 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 生成器映射。
Spring Boot 3.0 中删除了对以下依赖项的支持:
已删除对
Apache Solr
的支持,因为其基于Jetty
的客户端Http2SolrClient
与Jetty 11
不兼容。