一句话先说结论:Spring Boot 3 是基于 Spring Framework 6 的平台级升级,最低要求 Java 17,并把整个生态从
javax.*迁移到jakarta.*。升级后最先崩的往往是满屏的包找不到——javax.persistence、javax.servlet这些全都要改成jakarta.*。再叠上 Spring Security 6 移除了WebSecurityConfigurerAdapter、Hibernate 升到 6,升级是一项“重命名 + 重写”的工程。
背景
Spring Boot 3.x 于 2022 年末发布,踩在三大变化之上:
- JDK 强制升到 17+,Java 8 / 11 不再支持。
- Jakarta EE 9+ 命名空间迁移:
javax.*全部改为jakarta.*。 - 生态大版本同步升级:Spring Framework 6、Spring Security 6、Hibernate 6、Tomcat 10。
所以它不是“小版本点一下”,而是把好几条兼容性边界同时跨过去。
现象
升级之后最常见的两类报错:
一是 Java 版本不够:
UnsupportedClassVersionError: com/example/Application (class file version 61.0)
(class file version 61.0 对应的就是 Java 17。)
二是满屏的包找不到:
import javax.persistence.Entity; // error: package javax.persistence does not exist
import javax.servlet.http.HttpServletRequest; // error
import javax.validation.constraints.NotNull; // error
Hibernate/JPA 实体的 @Entity、@Column 等注解直接失效。
根因分析
这个 javax → jakarta 的变化,源头不在 Spring,而在整个 Java 企业生态。
2017 年 Oracle 把 Java EE 交给 Eclipse 基金会,规范、参考实现、TCK 都捐了,但 javax 这个命名空间商标 Oracle 没放。Eclipse 基金会不能修改 javax.* 包并以 Java EE 名义发布,于是整体改名:Java EE 变成 Jakarta EE,企业级包名从 javax.* 换成 jakarta.*。Jakarta EE 9 是第一次纯改名发布,不做新特性,就只是换包名。Spring Boot 3 / Spring Framework 6 跟随采用了这套新命名空间。
这里有个最容易误伤的点:不是所有 javax 都要改。只有原来属于 Java EE 的包才变了,JDK 核心自带的 javax 没动:
| 要改(原 Java EE) | 不改(JDK 自带) |
|---|---|
javax.persistence → jakarta.persistence |
javax.sql |
javax.servlet → jakarta.servlet |
javax.crypto |
javax.validation → jakarta.validation |
javax.net.ssl |
javax.annotation → jakarta.annotation |
javax.swing |
javax.inject / javax.transaction → jakarta.* |
javax.naming |
所以批量替换时得用白名单,不能无脑把所有 javax 都换掉。
解决方案
1. 先升 JDK 到 17
pom.xml:
<properties>
<java.version>17</java.version>
</properties>
Gradle:
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
2. 批量替换 Jakarta 包名
只改 Jakarta EE 相关的那几个前缀,用 IDE 的 Find in Files → Replace in Files 一键替换:
javax.servlet → jakarta.servlet
javax.persistence → jakarta.persistence
javax.validation → jakarta.validation
javax.annotation → jakarta.annotation
javax.transaction → jakarta.transaction
替换后:
// Before (Boot 2.x)
import javax.persistence.Entity;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
// After (Boot 3.x)
import jakarta.persistence.Entity;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
依赖坐标也跟着换,例如:
// Boot 2.x
implementation 'javax.validation:validation-api'
// Boot 3.x
implementation 'jakarta.validation:jakarta.validation-api'
3. 重写 Spring Security 配置
Spring Security 6 彻底移除了 WebSecurityConfigurerAdapter,改成 SecurityFilterChain Bean + Lambda DSL:
// ❌ Boot 2.x(已删除)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated();
}
}
// ✅ Boot 3.x
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
}
方法是 antMatchers → requestMatchers、authorizeRequests → authorizeHttpRequests,链式 .and() 改成 Lambda。
4. 检查第三方依赖和配置项
- Swagger/SpringFox 不支持 Jakarta,换成
springdoc-openapi-starter-webmvc-ui。 - 老版 Hibernate(5.x)不支持 Jakarta,必须升到 Hibernate 6。
- 配置键有一批被重命名/删除,典型如
spring.redis.*→spring.data.redis.*。可以临时引入spring-boot-properties-migrator,它会在启动时打印哪些旧配置键该改。 - Hibernate 6 的 HQL / dialect 有差异,
session.createQuery("from User")最好改成带上返回类型createQuery("from User", User.class)。
5. 用工具省力
大项目手动替换容易漏。可以用 OpenRewrite 的迁移 recipe 自动重写 javax.* imports 和依赖版本;spring-boot-properties-migrator 负责提示配置项迁移。
小结
- 这次升级的关键词是“重命名 + 重写”:
javax→jakarta、WebSecurityConfigurerAdapter→SecurityFilterChain、Hibernate 5 → 6。 javax替换一定要分清楚哪些是 Jakarta EE、哪些是 JDK 自带,别误伤javax.sql这类。- 顺序建议:先升 JDK 17 → 再做包名替换 → 重写 Security → 逐个校验第三方库的 Jakarta 兼容版本。
- 升级后跑一遍
spring-boot-properties-migrator,比手工翻 migration guide 更不容易漏。