Spring Boot 3.5 在项目里「常用且本质」的变化,可以分成两类:必须改的底座,和日常开发会真正用到的能力。
一、项目里必须接受的 5 个本质改变
这些是 2.x → 3.x 的「换地基」,不处理就跑不起来或隐患很大。
1. Java 17 起步
<!-- pom.xml -->
<properties>
<java.version>17</java.version>
</properties>
项目影响:
- 构建、CI、Docker 镜像都要升到 JDK 17+
- 可以开始用
record、文本块、switch表达式等 - 还在 Java 8/11 的老项目,先升 JDK,再升 Spring Boot
2. javax → jakarta(改动面最大)
几乎凡是用到 Servlet、JPA、Validation、JAX-RS 的地方都要改:
// 2.x
import javax.persistence.Entity;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
// 3.5
import jakarta.persistence.Entity;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
项目影响:
- 业务代码、Filter、Interceptor、Entity 全要扫一遍
- 第三方 jar 必须支持 Jakarta(老版 Swagger、部分工具包会卡住)
- 这是迁移时 工作量最大 的一块
3. Spring Security 写法彻底换一套
2.x 常见写法:
// 已废弃
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()...
}
}
3.5 项目里标准写法:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.csrf(csrf -> csrf.disable()) // 纯 JWT API 常要显式处理
.build();
}
}
项目影响:
- 所有安全配置类要重写
authorizeRequests()→authorizeHttpRequests()antMatchers()→requestMatchers()
4. 持久层跟着 Hibernate 6 变
项目里常见变化:
// 分页查询要显式写 countQuery(很多 2.x 项目会踩坑)
@Query(value = "SELECT u FROM User u WHERE u.status = :status",
countQuery = "SELECT count(u) FROM User u WHERE u.status = :status")
Page<User> findByStatus(@Param("status") String status, Pageable pageable);
项目影响:
- 实体映射、方言、时间类型、JSON 字段行为可能和 2.x 不一致
- 启动后要多跑一轮 CRUD、分页、复杂查询回归
- Flyway/Liquibase 脚本有时要适配新方言
5. 配置项和依赖版本整体换代
项目里要习惯的事:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.x</version>
</parent>
- 很多
spring.*配置项改名或语义收紧(3.5 里.enabled只认true/false) - Actuator 端点权限更严(如
heapdump默认不开放) - Redis、Prometheus Pushgateway 等部分配置 key 有变化
升级时可临时加:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
启动日志会提示哪些配置过时/无效。
二、3.5 项目里「日常真会用」的能力
这些是升到 3.x 后,新项目或重构时最常落地的,不是纸上谈兵。
1. 虚拟线程(高并发 I/O 项目很实用)
spring.threads.virtual.enabled=true
适合:
- 大量 HTTP 调用、RPC、数据库 I/O
- 不想上 WebFlux,又想提高并发
项目本质:还是同步写法,但底层线程模型变了,少写一套响应式。
2. RestClient 替代 RestTemplate
@Service
public class UserService {
private final RestClient restClient;
public UserService(RestClient.Builder builder) {
this.restClient = builder.baseUrl("https://api.xxx.com").build();
}
public UserDTO getUser(Long id) {
return restClient.get()
.uri("/users/{id}", id)
.retrieve()
.body(UserDTO.class);
}
}
项目本质:外部接口调用代码更简洁,新代码别再用 RestTemplate。
3. 声明式 HTTP Client(@HttpExchange)
@HttpExchange("/api/order")
public interface OrderClient {
@GetExchange("/{id}")
OrderDTO getById(@PathVariable Long id);
}
项目本质:轻量替代 Feign,适合内部服务调用,接口即客户端。
4. Docker Compose / Testcontainers(本地开发和测试)
# compose.yaml
services:
mysql:
image: mysql:8
ports: ["3306:3306"]
@SpringBootTest
@Testcontainers
class OrderServiceTest {
@Container
@ServiceConnection
static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8");
}
项目本质:
- 本地不用手启 MySQL/Redis/Kafka
- 集成测试少写一堆
@DynamicPropertySource
5. 结构化日志(上云、接 ELK/Loki 几乎必备)
logging.structured.format.console=ecs
logging.structured.format.file=logstash
项目本质:日志从「给人看」变成「给系统采集」,运维和排障方式变了。
6. 可观测性默认更强
// 业务代码可挂 Observation
Observation.createNotStarted("order.create", registry)
.observe(() -> orderService.create(dto));
配合:
- Actuator
- Micrometer
- OpenTelemetry(3.5 对
OTEL_*环境变量支持更好)
项目本质:监控不再全靠手写埋点,框架层统一了指标/链路接入方式。
7. 3.5 新增的「项目向」小改动
这些不华丽,但进项目后很实用:
| 能力 | 项目里干嘛用 |
|---|---|
@FilterRegistration / @ServletRegistration |
注册 Filter/Servlet,少写 RegistrationBean |
spring.config.import=env:XXX |
K8s/容器里一段环境变量导入多行配置 |
| WebClient 全局超时配置 | 统一外部调用超时,不用每个 Client 手写 |
| SSL Bundle + 证书指标 | HTTPS 证书过期监控,生产环境很有用 |
| Bean 后台初始化 | 大项目启动优化 |
三、落到项目结构上的「本质变化」
如果从 2.x 项目视角看,变化其实是这几层:
2.x 项目 3.5 项目
────────────────────────────────────────────────
Java 8/11 → Java 17+
javax 包 → jakarta 包
Security 继承 Adapter → SecurityFilterChain Bean
RestTemplate → RestClient / @HttpExchange
手写测试容器配置 → @ServiceConnection
普通线程池扛并发 → 可选虚拟线程
文本日志 → 结构化 JSON 日志
零散监控埋点 → Observation + Actuator 统一体系
本地手启中间件 → compose.yaml 自动管理
可以概括成一句话:
3.5 不是多几个注解,而是项目从「传统 Servlet + javax + 同步线程」切到「Jakarta + 现代 Java + 云原生运维」这一套。
四、如果你现在就要动一个老项目,优先改什么
按优先级:
- JDK 17
javax→jakarta- Security 配置重写
- Hibernate/JPA 回归测试
- 废弃配置清理(用 properties-migrator)
- 新代码开始用 RestClient / 结构化日志 / 虚拟线程
五、结合真实业务的判断
| 项目类型 | 3.5 最值得先上的 |
|---|---|
| 对外 API / 微服务 | Jakarta 迁移 + Security + RestClient + 结构化日志 |
| 高并发查询服务 | 虚拟线程 |
| 重集成测试 | Testcontainers + @ServiceConnection |
| 金融/政企后台 | SSL 证书监控 + Actuator 权限收紧 |
| 还在 2.7 维护态 | 先停在新功能,规划 2.7 → 3.0 迁移 |