Spring Boot 3 的发布带来了底层框架、模块命名空间与运行时约束的全面调整。如果你直接把 pom.xml 或 build.gradle 中的版本号从 2.x 改成 3.x,大概率会撞上一堆包扫描失败、自动配置不生效、配置键失效等问题。这篇文章从实际迁移视角切入,拆解 Spring Boot 2 与 3 在依赖坐标、自动配置机制、Web 开发、安全框架、可观测性以及原生编译方面的核心差异,并给出可落地的升级检查项。

基础运行环境与依赖坐标的硬性变化
Spring Boot 3 将 Java 17 作为最低版本要求,不再支持 Java 8 或 Java 11。这意味着迁移前必须先升级 JDK,并确认所有依赖包均有兼容 Java 17 的版本。底层框架也从 Spring Framework 5 切换到 Spring Framework 6,后者基于 Jakarta EE 9 及以上版本,导致大量包的根路径从 javax.* 迁移到 jakarta.*。例如 servlet、validation、persistence、transaction 等 API 的包名都发生了变化。旧项目中常见的 javax.servlet.http.HttpServletRequest、javax.persistence.Entity、javax.validation.Valid 等导入语句必须替换为对应的 jakarta 前缀版本,否则编译阶段就会报错。
Maven 项目中的 <parent> 坐标版本需要同步调整,示例配置如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<properties>
<java.version>17</java.version>
</properties>
除了 JDK 和 Jakarta 包切换,一些第三方库也需要升级到新的大版本。例如 Hibernate 升级到 6.x,Lombok、MapStruct、MyBatis、Flyway、QueryDSL 等常用组件都必须检查兼容性。如果项目中存在自定义的 Starter 或自动配置模块,还需要同步修改自动配置注册文件,否则 Spring Boot 3 将无法识别这些配置类。
另外,变量名、方法签名也出现了一些断裂式变更。比如 Spring Framework 6 中对部分工具类的构造方法进行了私有化处理,常见的 new AnnotationConfigApplicationContext() 仍然可用,但某些基于反射的工具类调用方式会失效。因此,升级前最好使用 IDE 的编译错误列表逐项处理,而不是只盯着启动日志。
自动配置机制与配置属性的调整
Spring Boot 2.7 开始引入新的自动配置注册方式,到了 Spring Boot 3 中,旧的 spring.factories 文件写法被彻底移除。以前需要在 META-INF/spring.factories 中用 org.springframework.boot.autoconfigure.EnableAutoConfiguration 键来列出配置类,现在必须使用 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,并且每行只写一个配置类的全限定名。这个变化对自定义 Starter 影响最大,很多内部公共组件升级后会突然失去自动装配能力。
旧版 spring.factories 写法如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.config.MyAutoConfiguration
新版 AutoConfiguration.imports 文件内容则直接写:
com.example.config.MyAutoConfiguration
注意目录路径从 META-INF/spring.factories 变为 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,文件名也完全改变。Spring Boot 3 不再读取 spring.factories 中的自动配置信息。虽然它仍会读取其他类型的 spring.factories 条目,比如 ApplicationContextInitializer、EnvironmentPostProcessor 等,但自动配置部分必须迁移到新文件。
配置属性键名也有一批被重命名或移除。最常见的是 Redis 相关配置,spring.redis.* 在 Spring Boot 2 中广泛使用,而 Spring Boot 3 将其调整为 spring.data.redis.*。类似地,Elasticsearch 的旧版属性 spring.elasticsearch.rest.* 被移除,改用 spring.elasticsearch.*。如果升级后配置不生效但启动不报错,很可能是旧属性被静默忽略了。建议迁移时搜索项目中所有 spring.redis、spring.elasticsearch、management.metrics 相关属性并逐一替换。
自动配置的条件注解也有变化。Spring Boot 3 对 @ConditionalOnBean、@ConditionalOnMissingBean 的求值时机和容器刷新顺序做了优化,一些依赖 Bean 定义顺序的自定义配置类可能出现判断结果不一致的情况。如果遇到某些 Bean 有条件装配但结果不符合预期,建议先在测试中显式声明依赖关系,而不是完全依赖条件注解。
Web、安全与数据访问层的演进
Web 层一个明显的差异是 Spring Framework 6 引入了 HttpStatusCode 接口来替代直接使用整型状态码的部分场景,并且 MVC 异常处理新增了对 ProblemDetail 和 ErrorResponse 的支持。Spring Boot 3 内置的 DefaultErrorAttributes 和 BasicErrorController 行为虽然保持兼容,但如果你在 Spring Boot 2 中自定义了错误响应结构,升级后需要检查 ErrorAttributes 的返回内容是否还符合前端约定。
安全框架方面,Spring Security 5.8 起提供新的 HttpSecurity 配置 API,Spring Boot 3 默认使用 Spring Security 6,旧的 authorizeRequests() 和 antMatchers() 已被标记废弃并删除。新的配置方式使用 authorizeHttpRequests() 和 requestMatchers()。一个典型的新版安全配置如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth ->
auth.requestMatchers("/api/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(form ->
form.loginPage("/login").permitAll()
)
.logout(logout ->
logout.logoutUrl("/logout").logoutSuccessUrl("/login")
);
return http.build();
}
}
如果迁移后出现 WebSecurityConfigurerAdapter 找不到类或 authorizeRequests() 方法无法解析的情况,说明还在使用旧版安全配置。需要彻底移除继承关系,改为基于 SecurityFilterChain Bean 的组件化配置。同时注意 requestMatchers() 的匹配规则更细粒度,旧的 antMatchers() 方法已被删除,不能再使用。
数据访问方面,Spring Boot 3 默认集成 Hibernate 6,带来的影响不只是依赖升级。Hibernate 6 对实体映射、命名策略和 HQL 解析做了较大调整。例如 Hibernate 6 默认的 PhysicalNamingStrategy 和 ImplicitNamingStrategy 与 5.x 存在差异,可能导致数据库表名或列名映射结果不同。另外,HQL 中某些旧语法被收紧,实体必须显式使用别名,否则会抛出解析异常。如果项目中有复杂报表查询或原生 SQL 映射,升级后需要重新执行回归测试。
可观测性、AOT 与原生镜像增强
Spring Boot 3 在可观测性上最大的变化是引入 Micrometer Observation API,统一了指标、追踪和日志的关联方式。原先需要在代码里手动创建 Meter 或 Span 的场景,现在可以通过 ObservationRegistry 和 Observation 接口实现一次埋点,同时输出到不同后端。比如在 Web 层,Spring MVC 和 WebFlux 都提供了自动的观测支持,带来的好处是可以在不改业务代码的情况下获得完整的调用链和延迟统计。
可观测性相关的配置前缀也从 management.metrics.web.server.requests 调整为更清晰的 management.observations.http.server.requests 形式。很多旧监控看板依赖指标名称,迁移后需要同步更新 Prometheus 查询语句或 Grafana 面板。Spring Boot Actuator 的端点在 3.x 中变化不大,但健康检查组的配置方式更加结构化,旧的 management.health.* 有些键被移动到了 management.endpoint.health.* 下,需要留意。
AOT 编译和 GraalVM 原生镜像是 Spring Boot 3 的主推方向。它允许在构建阶段提前执行部分初始化逻辑,生成原生可执行文件,从而大幅降低内存占用和启动时间。对于短生命周期容器、Serverless 函数和云原生场景,这个增强非常实用。但原生镜像对反射、动态代理、资源文件加载有严格限制,Spring Boot 3 提供了 RuntimeHints API 来注册运行时需要的反射信息。一个常见的注册示例如下:
@Configuration
@ImportRuntimeHints(MyHints.class)
public class NativeConfig {
}
class MyHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(MyEntity.class);
hints.resources().registerPattern("mapper/*.xml");
}
}
如果项目并不打算原生编译,AOT 相关变化不会直接影响启动,但了解这一方向有助于后续架构选型。普通 JVM 模式仍然完全兼容,不需要额外配置。
迁移常见问题与注意事项
升级过程中最常见的一类报错是 java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest 或 ClassNotFoundException: javax.persistence.EntityManager。这是因为某些传递依赖仍然停留在旧版本,或者代码中还有未替换的 javax 导入。解决方式是通过全局搜索替换源代码中的 javax.servlet、javax.persistence、javax.validation 等包名,同时检查依赖树中是否有老旧组件强制引入 javax 版本,必要时排除旧依赖并升级对应组件。
另一个高频问题是自定义 Starter 不生效。检查点包括:是否已经创建 AutoConfiguration.imports 文件、文件路径是否完全正确、配置类上是否同时保留了 @Configuration 与 @AutoConfiguration 注解。Spring Boot 3 对自动配置类的包扫描限制更严格,建议配置类不要放在被业务组件扫描的根包下,否则可能产生重复装配或顺序混乱。
配置文件中的旧属性键也需要全面排查。尤其要注意 spring.redis.* 到 spring.data.redis.* 的替换、spring.datasource.hikari.* 到 spring.datasource.hikari.* 基本不变但部分驱动类名调整、以及 server.servlet.session.timeout 的单位语义是否变化。建议在测试环境开启 spring.boot.context.properties.migrator 或在启动日志中观察属性迁移提示,很多 Spring Boot 3 的版本会主动打印过时属性的警告。
安全配置迁移时,如果发现 WebSecurityConfigurerAdapter 无法继承,不要再尝试从旧版依赖中找回类,而是按要求重构为 SecurityFilterChain Bean。同时检查 URL 匹配表达式,旧版 antMatchers() 的某些通配符语义与新版 requestMatchers() 略有差异,尤其是 /** 与 /* 的匹配范围。权限表达式、登录成功处理器和异常处理器需要重新绑定到新的链式 API 中。
最后,升级完成后应分层验证,而不是直接上生产。先跑单元测试和集成测试,再在预发环境观察内存占用、启动时间、GC 情况和监控指标。Spring Boot 3 在 JVM 模式下与 2.x 相比性能提升并不夸张,稳定性主要受底层框架和第三方依赖的适配程度影响。如果项目规模较大,建议采用分模块逐步迁移的方式,先升级独立的基础组件和 Starter,再迁移主业务应用,避免一次性改动过大带来排查困难。
整体来看,Spring Boot 3 的演进方向是更严格的模块边界、更强的可观测性以及面向云原生的原生编译能力。对于新项目,直接使用 3.x 是合理选择;对于维护中的旧系统,则应根据依赖兼容性和团队人力,规划好迁移窗口与回归测试范围。
Spring Boot3版本差异迁移注意事项修改时间:2026-10-05 12:57:41