我们来详细探讨一下从 Spring Boot 2 升级到 Spring Boot 3 时的主要注解差异和配置注意事项。
核心变化:Java EE 迁移到 Jakarta EE
最根本和影响最广泛的变化是 Spring Boot 3(以及其基础 Spring Framework 6)将 Java 企业版规范从 Java EE 迁移到了 Jakarta EE 9/10。这意味着所有以前在 javax.*
包下的 API 都迁移到了 jakarta.*
包下。
一、 注解差异 (主要是包名变化)
最显著的注解变化来自于 Jakarta EE 的迁移。所有以前位于 javax.*
包下的标准 Java EE API 注解,现在都迁移到了 jakarta.*
包下。这意味着你需要更新代码中所有相关的 import
语句。
以下是一些常见的受影响的注解及其包名变化:
- Servlet API:
javax.servlet.*
->jakarta.servlet.*
- 例如:
javax.servlet.http.HttpServletRequest
->jakarta.servlet.http.HttpServletRequest
javax.servlet.Filter
->jakarta.servlet.Filter
javax.servlet.annotation.WebServlet
->jakarta.servlet.annotation.WebServlet
- 例如:
- JPA (Java Persistence API):
javax.persistence.*
->jakarta.persistence.*
- 例如:
javax.persistence.Entity
->jakarta.persistence.Entity
javax.persistence.Id
->jakarta.persistence.Id
javax.persistence.GeneratedValue
->jakarta.persistence.GeneratedValue
javax.persistence.Table
->jakarta.persistence.Table
- 例如:
- Bean Validation:
javax.validation.*
->jakarta.validation.*
- 例如:
javax.validation.Valid
->jakarta.validation.Valid
javax.validation.constraints.NotNull
->jakarta.validation.constraints.NotNull
javax.validation.constraints.NotBlank
->jakarta.validation.constraints.NotBlank
- 例如:
- 其他:
javax.annotation.PostConstruct
->jakarta.annotation.PostConstruct
javax.annotation.PreDestroy
->jakarta.annotation.PreDestroy
javax.annotation.Resource
(如果使用的话) ->jakarta.annotation.Resource
javax.websocket.*
->jakarta.websocket.*
javax.xml.bind.*
(JAXB) ->jakarta.xml.bind.*
除了包名变化,还有一些其他注解相关的调整:
@ConstructorBinding
: 在 Spring Boot 3 中,如果@ConfigurationProperties
类只有一个带参数的构造函数,则不再需要在类级别上添加@ConstructorBinding
注解,应该移除它。@EnableBatchProcessing
(Spring Batch): Spring Boot 3 不再推荐使用@EnableBatchProcessing
来启用 Spring Batch 的自动配置。如果想使用自动配置,应移除此注解。使用此注解(或定义 DefaultBatchConfiguration bean)会告诉自动配置退避(back off)。- Spring Security 注解: Spring Security 6 (Spring Boot 3 依赖) 有一些变化,虽然核心注解如
@PreAuthorize
等保持不变,但配置方式和某些内部实现可能影响注解的使用场景或需要调整配置类。 - Micrometer 注解 (Spring Boot 3.2+): 像
@Timed
,@Counted
,@Observed
等 Micrometer 提供的注解,在引入spring-boot-starter-aop
依赖后,其切面(Aspects)会被自动配置,简化了指标和追踪的声明。
二、 配置注意事项
升级到 Spring Boot 3 时,除了注解,还需要关注以下配置和环境方面的变化:
- Java 版本要求: Spring Boot 3 最低要求 Java 17。你需要确保你的开发环境和运行环境都已升级到 Java 17 或更高版本。
- Spring Framework 版本: Spring Boot 3 构建于 Spring Framework 6 之上。这意味着底层框架本身也有诸多变化和 API 调整。
- Jakarta EE 依赖版本: 确保你的项目依赖(如 Servlet API, JPA API)已更新到 Jakarta EE 9 或 10 兼容的版本(例如 Servlet 6.0, JPA 3.1)。如果你手动管理这些依赖,需要显式更新版本号。
- 配置文件 (
application.properties
/application.yml
) 变化:- 属性重命名/移除: 一些配置属性的名称或位置发生了变化,或者被移除了。例如:
spring.redis.*
移至spring.data.redis.*
spring.data.cassandra.*
移至spring.cassandra.*
server.max.http.header.size
移至server.max-http-request-header-size
- 移除了
spring.jpa.hibernate.use-new-id-generator-mappings
(Hibernate 6 不再支持旧的 ID 生成器映射) - 移除了对
spring.security.saml2.relyingparty.registration.{id}.identity-provider
的支持。
- 属性迁移器: 为了帮助识别和迁移这些属性,可以添加
spring-boot-properties-migrator
依赖。它会在应用启动时打印报告,指出哪些属性已废弃或更改,并能在运行时临时兼容旧属性。<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-properties-migrator</artifactId> <scope>runtime</scope> </dependency>
- 日志日期格式: Logback 和 Log4j2 的默认日志日期时间格式已更改为符合 ISO-8601 标准。
- Actuator 端点敏感信息:
/env
和/configprops
端点默认不再显示所有属性的值(出于安全考虑),而是默认隐藏。可以通过management.endpoint.env.show-values
和management.endpoint.configprops.show-values
配置来控制显示策略(如ALWAYS
,WHEN_AUTHORIZED
,NEVER
)。 - Web 应用路径匹配:
spring.mvc.pathmatch.matching-strategy
的默认值更改和spring.webflux.pathmatch.matching-strategy
相关配置可能需要关注。路径尾部斜杠匹配 (use-trailing-slash-match
) 相关的配置选项已被弃用,并且默认值为false
。
- 属性重命名/移除: 一些配置属性的名称或位置发生了变化,或者被移除了。例如:
- 自动配置文件:
- 在 Spring Boot 2.x 中,自动配置类通常在
META-INF/spring.factories
文件中通过org.springframework.boot.autoconfigure.EnableAutoConfiguration
键列出。 - 在 Spring Boot 3.x 中,推荐的方式是使用
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件来列出自动配置类。spring.factories
的这种用法已被弃用。
- 在 Spring Boot 2.x 中,自动配置类通常在
- 第三方库兼容性: 检查你项目依赖的所有第三方库是否都发布了与 Spring Boot 3 和 Jakarta EE 兼容的版本。这是升级过程中常见的问题点,可能需要升级库的版本,甚至替换不再兼容的库。例如,Dubbo 需要升级到 3.2+ 版本才支持 Spring Boot 3。
- Spring Security: 必须升级到 Spring Security 6.x。建议先在 Spring Boot 2.7 环境下升级到 Spring Security 5.8,解决其中的废弃项和变更,然后再升级到 Spring Boot 3 和 Spring Security 6。Spring Security 6 默认会对所有 Dispatch 类型(如
FORWARD
,INCLUDE
,ERROR
)应用安全过滤器,这可以通过spring.security.filter.dispatcher-types
属性配置。 - Spring Data: JPA 基于 Jakarta Persistence 3.1。Hibernate 默认升级到 6.1+,其 Group ID 也从
org.hibernate
变为org.hibernate.orm
。 - 移除的功能: 一些在 Spring Boot 2.x 中被标记为
@Deprecated
的类、方法和属性在 Spring Boot 3.0 中已被正式移除。升级前最好先处理掉代码中使用的废弃 API。图片 Banner 支持已被移除。 - 循环依赖: Spring Boot 2.6 及以后版本默认禁止循环依赖。如果你的代码中存在循环依赖,在升级到 Spring Boot 3 时需要解决这个问题(例如通过重构代码、使用
@Lazy
、ObjectProvider
或构造函数注入BeanFactory
来延迟获取 bean)。
升级建议步骤:
- 确保当前版本: 将你的 Spring Boot 2.x 应用升级到最新的 2.7.x 版本。这是官方推荐的升级路径起点。
- 升级 Java 版本: 将 JDK 升级到 17 或更高版本。
- 处理废弃项: 在 Spring Boot 2.7 环境下,处理掉所有已标记为
@Deprecated
的 API 调用。 - 升级 Spring Security (如果使用): 在 Spring Boot 2.7 环境下升级到 Spring Security 5.8,并根据其迁移指南进行调整。
- 更新 Spring Boot 版本: 在
pom.xml
或build.gradle
中将 Spring Boot 版本更新到 3.x。 - 添加属性迁移器: 加入
spring-boot-properties-migrator
依赖,启动应用查看属性变更报告。 - 修改包名: 全局搜索并将
javax.*
替换为jakarta.*
。IDE 通常有工具可以辅助批量替换。 - 更新第三方依赖: 检查并升级所有第三方依赖到兼容 Spring Boot 3 和 Jakarta EE 的版本。
- 更新配置文件: 根据属性迁移器的报告和官方文档,更新
application.properties/yml
文件。 - 处理特定模块变更: 根据你使用的 Spring Boot 模块(如 Spring Batch, Spring Data, Spring Security 等),查阅相应的迁移指南进行调整。
- 编译和测试: 编译项目,解决编译错误。进行全面的单元测试、集成测试和功能测试。
升级过程可能比较复杂,特别是对于大型项目。建议逐步进行,并充分利用官方迁移指南和社区资源。