Spring Boot 4.0 正式发布:新一代起点到底“新”在哪?(Spring Framework 7 / Java 25 / JSpecify / API 版本管理 / HTTP Service

Spring Boot 4.0 正式发布:新一代起点到底"新"在哪?(Spring Framework 7 / Java 25 / JSpecify / API 版本管理 / HTTP Service Clients)

2025 年 11 月,Spring Boot 4.0.0 GA 悄悄发布。它不是"又一波依赖升级"那么简单,而是一次基线换代 + 体系补齐 :从 Java/Jakarta 基线、空安全体系,到 API 版本管理、声明式 HTTP Client,再到模块拆分与生态对齐,整体都更像 Spring Boot 进入了一个新世代。 (Home)


1. 先把结论摆在前面:4.0 是"换代",不是"升级"

Spring Framework 7.0 是 Spring 的新一代基础设施,它明确以 Java 25 为重点 、同时 保留 Java 17 baseline ,并升级到 Jakarta EE 11 (Servlet 6.1、JPA 3.2、Bean Validation 3.1 等),而 Spring Boot 4.0 正是建立在这套基线上。 (Home)

Spring Boot 4.0 发布公告把几个最关键点总结得很直白:代码库模块化JSpecify 空安全Java 25 一等公民支持 、以及 API 版本管理与 HTTP Service Clients 。 (Home)


2. 基线变化:你升级踩坑,大多都来自这里

2.1 Java 版本策略:Java 17 还能用,但"建议你上 25"

  • Spring Boot 4.0 要求 Java 17+ 。 (GitHub)
  • Spring Framework 7.0/Boot 4.0 强调对 Java 25 的拥抱 ,但同时保留 Java 17 baseline,便于企业逐步迁移。 (Home)

这意味着:

  • 你的生产集群短期还在 Java 17:可以升级 Boot 4
  • 但想吃到一些"新红利"(例如更顺滑的虚拟线程落地、生态最新适配),上 Java 25 会更舒服

2.2 Jakarta EE 11 + Servlet 6.1:服务器容器直接"换档"

Spring Framework 7.0 明确把 Servlet 6.1 作为 baseline,并指出需要部署到 Tomcat 11+ / Jetty 12.1+ 这类新容器。 (GitHub)

Undertow 为什么被移除?

因为 Undertow 还没兼容 Servlet 6.1 ,所以 Boot 4.0 直接砍掉 Undertow 支持 (包括 starter、embedded server 能力)。 (GitHub)

现实影响:以前 spring-boot-starter-undertow 的项目,升级 4.0 基本等价于"必须换容器"。


3. 开发者最该关注的 6 个"真新特性"

3.1 HTTP Service Clients:终于不用手写一堆模板代码了

Boot 4.0 为 HTTP Service Clients 提供了自动配置与配置属性支持:你只写接口,Spring 帮你生成实现。 (GitHub)

接口定义示例(最小可用版) (与官方示例一致): (GitHub)

java 复制代码
import java.util.Map;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.PostExchange;

@HttpExchange(url = "https://echo.zuplo.io")
public interface EchoService {

  @PostExchange
  Map<?, ?> echo(@RequestBody Map<String, String> message);

}
生产级写法:不要把 URL 写死在注解里(用"分组 + 配置")

Spring Boot 4 的文档给了更工程化的方式:用 @ImportHttpServices 把一组 Client 注册进来,然后用配置注入 base-url、超时、Header 等。 (Home)

注册 HTTP Services(扫描包 + 绑定 group) : (Home)

java 复制代码
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.service.registry.ImportHttpServices;

@SpringBootApplication
@ImportHttpServices(group = "echo", basePackages = "com.example.myclients")
public class MyApplication { }

配置 base-url(避免硬编码) : (Home)

properties 复制代码
spring.http.serviceclient.echo.base-url=https://echo.zuplo.io

你还可以在同一组里统一配置超时、默认 header、SSL、甚至把 API 版本信息自动塞进请求头 (下面会讲)。 (Home)


3.2 原生 API 版本管理:终于不用各写各的"版本路由方案"了

Boot 4.0 为 Spring MVC / WebFlux 都加入了 API Versioning 的自动配置,核心配置入口是:

  • spring.mvc.apiversion.*
  • spring.webflux.apiversion.* (GitHub)

Spring Boot 文档给了一个非常直接的例子:用 X-Version 请求头作为版本来源,默认版本为 1.0.0。 (Home)

properties 复制代码
spring.mvc.apiversion.default=1.0.0
spring.mvc.apiversion.use.header=X-Version

并且,如果你要更强的控制能力,可以自己定义 ApiVersionResolver / ApiVersionParser / ApiVersionDeprecationHandler Bean 来接管解析与废弃策略。 (GitHub)

更"爽"的点:客户端也能自动插版本

HTTP Service Clients 那边同样支持通过配置,把版本自动插入 header: (Home)

properties 复制代码
spring.http.serviceclient.echo.apiversion.default=1.0.0
spring.http.serviceclient.echo.apiversion.insert.header=X-Version

这很重要:以前你做版本管理,经常只做了"服务端路由",但调用端(服务间调用)依旧要手写版本 header;现在能用配置统一治理。


3.3 JSpecify 空安全:把 NPE 从"线上炸弹"变成"编译期问题"

Spring Framework 7.0 把 Spring 旧的 nullness 注解(JSR-305 语义)逐步转向 JSpecify ,并强调"全面空安全"。 (GitHub)

Boot 4.0 发布公告也把它列为核心变化之一:Portfolio-wide improvements for null safety with JSpecify 。 (Home)

你可以把它理解为:

  • 在代码层更明确表达"默认不为 null,只有标注才可为 null"
  • 配合静态分析(例如 NullAway 等)能把很多空指针风险提前拦截

对团队价值极高:尤其是多人协作的 SDK/公共组件层,空语义清晰会显著减少"靠约定"的沟通成本。


3.4 虚拟线程:不只是"能开",而是"默认帮你用到位"

Boot 4.0 release notes 里提到一个很实用的点:当你启用
spring.threads.virtual.enabled=true

自动配置的 JDK HttpClient 会默认使用虚拟线程。 (GitHub)

这意味着:

  • IO 密集型服务(大量远程调用、数据库/Redis、第三方接口)在虚拟线程下更容易拿到吞吐提升
  • 并且它不是"你得自己改一堆代码",而是更偏"配置即收益"

注意:虚拟线程不是银弹。你仍然要关注阻塞点是否可控、连接池是否合理、以及下游是否被你压垮。


3.5 Redis 静态主从:不再强迫你上 Sentinel/Cluster

Boot 4.0 新增 Redis Static Master/Replica 的自动配置(仅 Lettuce 支持),用一个新配置就能指定静态节点: (GitHub)

properties 复制代码
spring.data.redis.masterreplica.nodes=host1:6379,host2:6379

适合这种场景:

  • 你在一个相对稳定的 Redis 主从拓扑里(比如云厂商固定主从)
  • 你不想引入 Sentinel/Cluster 的复杂度
  • 你只需要"读写分离 / 主从切换由外部保障",应用侧只要正确连就行

3.6 Gradle 9 / 依赖大跃迁 / 模块化:工程侧变化非常集中

  • Boot 4.0 明确 支持 Gradle 9 ,并保留 Gradle 8.14+ 支持。 (GitHub)
  • 依赖升级极其集中:例如 Jackson 3.0、Hibernate 7.1、Kafka 4.1、Jetty 12.1、Tomcat 11、Kotlin 2.2.20 等都在"核心清单"里。 (GitHub)
  • 并且 Boot 4.0 强调"更彻底的模块化",产出更小、更聚焦的 jar/模块。 (Home)

工程上的真实影响通常是:

  1. 依赖冲突更容易暴露(因为生态统一升级)
  2. 一些"你以前没显式引 starter 但也能跑"的能力,在模块拆分后可能需要你显式加 starter(Boot migration guide 已经点出来了)。 (GitHub)

4. 升级路线:别头铁,官方建议很明确

4.1 最推荐的路径:先到 3.5.x,再升 4.0

Migration Guide 直接写明:升级前先升到最新 3.5.x ,能显著减少坑(尤其是先清理 3.x 中已废弃 API,因为 4.0 会移除)。 (GitHub)


5. 一份"可复制"的升级 Checklist(建议你照着做)

Step 0:锁定升级窗口 + 做好回滚

  • 这是大版本升级:建议以"一个服务一个分支"推进
  • 先让 CI 跑通,再做预发/压测

Step 1:先升级到最新 3.5.x

  • 目标:提前消化 3.x 的废弃项(4.0 会删) (GitHub)

Step 2:确认基线与容器

  • Java ≥ 17(建议 Java 25) (GitHub)
  • Servlet 6.1 容器:Tomcat 11+/Jetty 12.1+ (GitHub)
  • Undertow:直接迁移(Boot 4.0 不支持) (GitHub)

Step 3:关注 Jackson 3 迁移

Migration Guide 强烈建议尽可能迁移到 Jackson 3,并提供了一个过渡模块 spring-boot-jackson2(但它是 stop-gap,会在未来移除)。 (GitHub)

这里通常是升级中最"费时间"的部分:你需要排查自定义序列化、老 API、以及某些三方库是否还绑死 Jackson 2。

Step 4:关注 HttpMessageConverters 相关变更

Boot 4.0 migration guide 提到 HttpMessageConverters 被弃用,并给了新的 client/server converter customizer 方式。 (GitHub)

如果你项目里有"自定义 converter 注入"之类的老写法,重点回归测试接口序列化。

Step 5:顺手把"新能力"纳入工程规范

  • 内部服务调用:试点 HTTP Service Clients(至少替换一两个 RestTemplate/Feign 场景)
  • API 演进:统一版本策略(header / param / path),把调用端版本注入也配置化 (Home)
  • Redis:如果你是固定主从拓扑,考虑静态主从配置简化方案 (GitHub)

6. 总结:为什么说 Boot 4.0 更像"新世代起点"?

Spring Boot 4.0 的"新",不只是依赖升级,而是把很多过去"你自己造轮子/各团队各写各的"的能力,做成了标准能力

  • 声明式 HTTP Client + 配置化治理(URL/超时/header/版本) (GitHub)
  • 原生 API 版本管理 (MVC/WebFlux/客户端一致性) (GitHub)
  • JSpecify 空安全体系 ,把可维护性前移到编译期 (GitHub)
  • Servlet 6.1 / Jakarta EE 11 基线落地,生态整体换挡(顺带清理 Undertow 等"跟不上"的模块) (GitHub)
  • Gradle 9、依赖大跃迁、模块化 ,让工程更现代也更"讲规矩" (GitHub)

如果你愿意,我也可以按你当前项目情况,给你出一份更"落地"的 CSDN 后半篇:

  • 从 Boot 3.5 升 4.0 的真实改动点清单(按 Web / Data / JSON / Test / Build 分类)
  • 以及最常见的 10 个升级报错与修复示例(适合直接贴到文章里当"实战踩坑篇")。
相关推荐
William_cl6 小时前
ASP.NET入门必吃透:HTTP 协议从流程到状态码,代码 + 避坑指南
后端·http·asp.net
龙茶清欢6 小时前
WebClient:Spring WebFlux 响应式 HTTP 客户端权威说明文档
java·spring·http
AI大佬的小弟6 小时前
Python基础(10):Python函数基础详解
开发语言·python·函数·ai大模型基础·嵌套函数·变量的作用域·全局变量和局部变量
SZ1701102316 小时前
N-S图 (盒图) N-S图是“盒子嵌套”,PAD图是“树干分叉”*
python
Evand J6 小时前
【2026课题推荐】基于累计概率方法匹配轨迹的飞行目标轨迹定位,附MATLAB代码的演示效果
开发语言·matlab·目标跟踪·定位·轨迹匹配
_200_6 小时前
Lua 基本数据类型
开发语言·junit·lua
智航GIS6 小时前
8.5 os 模块
python
没有bug.的程序员6 小时前
网关在高并发场景下的优化实践:从Reactor模型到GC调优的深度指南
java·jvm·高并发·gc调优·网关优化·reactor模型·netty调优
独自破碎E6 小时前
Spring Boot 2.x和1.x版本相比有哪些区别与改进?
java·spring boot·后端