Spring Boot 4.0 官宣:弃用 Undertow

大家好,我是Java1234_小锋老师。

先说结论

Spring Boot 4.0 已经移除了对 Undertow 的官方支持,spring-boot-starter-undertow 不再随 Spring Boot 4 发布,内嵌 Undertow 的自动配置也被一并删除。

严格来说,这次变化并不只是给 Undertow 加上一个"未来可能删除"的弃用标记,而是直接移除支持。如果现有项目使用 Spring Boot 3.x + Undertow,那么升级到 Spring Boot 4.0 时不能只改版本号,还需要把 Web 容器迁移到 Tomcat 或 Jetty。

好消息是,大多数普通 Spring MVC 项目不需要改业务代码,主要调整依赖并完成一轮回归测试即可。

为什么不再支持 Undertow

Spring Boot 4 基于 Jakarta EE 11,并把 Servlet API 的基线提升到了 Servlet 6.1。Spring Boot 4 发布时,Undertow 尚未提供可供 Spring Boot 稳定集成的 Servlet 6.1 版本,因此官方选择删除 Undertow Starter、自动配置和内嵌服务器支持。

这条变化可以简单理解为:
#mermaid-svg-EXkGxCQvQ0WAnwzq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-EXkGxCQvQ0WAnwzq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-EXkGxCQvQ0WAnwzq .error-icon{fill:#552222;}#mermaid-svg-EXkGxCQvQ0WAnwzq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EXkGxCQvQ0WAnwzq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EXkGxCQvQ0WAnwzq .marker.cross{stroke:#333333;}#mermaid-svg-EXkGxCQvQ0WAnwzq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EXkGxCQvQ0WAnwzq p{margin:0;}#mermaid-svg-EXkGxCQvQ0WAnwzq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EXkGxCQvQ0WAnwzq .cluster-label text{fill:#333;}#mermaid-svg-EXkGxCQvQ0WAnwzq .cluster-label span{color:#333;}#mermaid-svg-EXkGxCQvQ0WAnwzq .cluster-label span p{background-color:transparent;}#mermaid-svg-EXkGxCQvQ0WAnwzq .label text,#mermaid-svg-EXkGxCQvQ0WAnwzq span{fill:#333;color:#333;}#mermaid-svg-EXkGxCQvQ0WAnwzq .node rect,#mermaid-svg-EXkGxCQvQ0WAnwzq .node circle,#mermaid-svg-EXkGxCQvQ0WAnwzq .node ellipse,#mermaid-svg-EXkGxCQvQ0WAnwzq .node polygon,#mermaid-svg-EXkGxCQvQ0WAnwzq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EXkGxCQvQ0WAnwzq .rough-node .label text,#mermaid-svg-EXkGxCQvQ0WAnwzq .node .label text,#mermaid-svg-EXkGxCQvQ0WAnwzq .image-shape .label,#mermaid-svg-EXkGxCQvQ0WAnwzq .icon-shape .label{text-anchor:middle;}#mermaid-svg-EXkGxCQvQ0WAnwzq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-EXkGxCQvQ0WAnwzq .rough-node .label,#mermaid-svg-EXkGxCQvQ0WAnwzq .node .label,#mermaid-svg-EXkGxCQvQ0WAnwzq .image-shape .label,#mermaid-svg-EXkGxCQvQ0WAnwzq .icon-shape .label{text-align:center;}#mermaid-svg-EXkGxCQvQ0WAnwzq .node.clickable{cursor:pointer;}#mermaid-svg-EXkGxCQvQ0WAnwzq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-EXkGxCQvQ0WAnwzq .arrowheadPath{fill:#333333;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EXkGxCQvQ0WAnwzq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EXkGxCQvQ0WAnwzq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-EXkGxCQvQ0WAnwzq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EXkGxCQvQ0WAnwzq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-EXkGxCQvQ0WAnwzq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EXkGxCQvQ0WAnwzq .cluster text{fill:#333;}#mermaid-svg-EXkGxCQvQ0WAnwzq .cluster span{color:#333;}#mermaid-svg-EXkGxCQvQ0WAnwzq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EXkGxCQvQ0WAnwzq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-EXkGxCQvQ0WAnwzq rect.text{fill:none;stroke-width:0;}#mermaid-svg-EXkGxCQvQ0WAnwzq .icon-shape,#mermaid-svg-EXkGxCQvQ0WAnwzq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EXkGxCQvQ0WAnwzq .icon-shape p,#mermaid-svg-EXkGxCQvQ0WAnwzq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-EXkGxCQvQ0WAnwzq .icon-shape .label rect,#mermaid-svg-EXkGxCQvQ0WAnwzq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EXkGxCQvQ0WAnwzq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-EXkGxCQvQ0WAnwzq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-EXkGxCQvQ0WAnwzq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 兼容
当时未满足要求
Spring Boot 4.0
Jakarta EE 11
Servlet 6.1 基线
内嵌容器是否兼容
Tomcat / Jetty
移除 Undertow 官方支持

这不代表 Undertow 本身"不能用了"或"性能不好"。问题的核心是版本基线、发布时间以及长期维护成本,而不是一次服务器性能排名。

升级后会遇到什么问题

假设 Spring Boot 3 项目原来这样引入 Undertow:

xml 复制代码
<!-- Spring Boot 3.x:排除默认 Tomcat,改用 Undertow -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

直接把 Spring Boot 升级到 4.0 后,Maven 会因为找不到对应版本的 spring-boot-starter-undertow 而构建失败。即使手动拼装 Undertow 依赖,原来由 Spring Boot 提供的自动配置类和属性适配也已经不存在,维护难度会明显增加。

方案一:切换到 Tomcat

Tomcat 仍然是最省心的选择,也是 Spring MVC 默认使用的内嵌容器。Spring Boot 4 对 Starter 做了进一步拆分,新的 MVC 项目建议直接使用 spring-boot-starter-webmvc:

xml 复制代码
<!-- Spring Boot 4:默认包含内嵌 Tomcat -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>

迁移时删除 spring-boot-starter-undertow,同时去掉对 spring-boot-starter-tomcat 的排除即可。Controller 通常不需要修改:

java 复制代码
package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 服务状态接口。
 */
@RestController
public class HealthController {

    /**
     * 返回当前服务状态,用于迁移后的连通性检查。
     *
     * @return 服务状态
     */
    @GetMapping("/health")
    public String health() {
        return "Spring Boot 4 is running";
    }
}

方案二:切换到 Jetty

如果团队原本就熟悉 Jetty,或者测试后发现它更符合项目需求,可以排除默认 Tomcat,再引入 Jetty:

xml 复制代码
<!-- Spring Boot 4:Spring MVC + Jetty -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webmvc</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

不要只凭"听说哪个容器更快"来决定。真实项目中的过滤器、上传下载、长连接、线程配置和监控体系都会影响结果。先用接近生产环境的流量做压测,再决定是否需要从默认 Tomcat 切换到 Jetty。

迁移时别忘了这些检查

容器替换看起来只是改几行 pom.xml,但以下内容很容易被遗漏:

  1. 检查 Java 版本:Spring Boot 4 最低要求 Java 17,官方建议优先使用较新的 LTS 版本。
  2. 搜索 Undertow 专属代码 :例如 io.undertow.*、UndertowServletWebServerFactory 和 Undertow 自定义 Handler。
  3. 清理专属配置 :删除 server.undertow.*,再根据实际压测结果配置 Tomcat 或 Jetty。
  4. 回归 Web 功能:重点测试文件上传、静态资源、错误页、压缩、HTTPS、WebSocket 和反向代理转发。
  5. 观察运行指标:对比迁移前后的启动时间、堆内存、线程数、吞吐量和 P99 响应时间。

可以先用 Maven 检查依赖树,确认 Undertow 已经彻底移除:

bash 复制代码
# 检查依赖树中是否还存在 Undertow
./mvnw dependency:tree -Dincludes=io.undertow

# 启动应用并进行基础回归验证
./mvnw spring-boot:run

还能继续使用 Undertow 吗

理论上可以自行维护集成层,或者等待社区提供适配 Spring Boot 4 的 Starter,但这已经不是 Spring Boot 官方开箱即用的能力。即使新版 Undertow 后续支持了 Servlet 6.1,也不等于官方 Starter 会自动回来。

Spring Boot 团队后来进一步说明,不计划重新引入官方 Undertow 支持;如果社区需求足够强,可以由社区维护独立模块。因此,对普通业务项目来说,升级时按 Tomcat 或 Jetty 进行规划更稳妥。只有在内存限制、既有基础设施等因素确实要求 Undertow 时,才值得承担第三方集成的版本兼容和长期维护成本。

写在最后

Spring Boot 4.0 移除 Undertow,表面上是少了一个内嵌服务器选项,背后其实是整个技术栈向 Jakarta EE 11 和 Servlet 6.1 迈进的结果。

如果你的项目没有使用 Undertow,这次变化基本无感;如果正在使用,也不必过度紧张。先清理 Undertow 专属依赖与配置,切换到 Tomcat 或 Jetty,再通过压测和回归测试验证,通常就是一条清晰、可控的升级路线。

相关推荐
jyOverQ1 小时前
Redis 主从复制、Sentinel 和 Cluster 到底有什么区别?
java·redis·sentinel
mldong1 小时前
给 Django Admin 加审批流:一行前端代码没写,298 行接上工作流引擎
后端·python·架构
高频因子挖掘机1 小时前
量化研究中,为什么拿到 Pandas 行情数据不等于完成数据接入?
后端·github·api
青春逝如流水2 小时前
Java 线程在内存模型(JMM)与 JVM 实现:规范与落地的多元路径
java·开发语言·jvm·多线程·ai文章
高频因子挖掘机3 小时前
股票 API 接入回测框架时最容易忽略的几个问题:复权、时间对齐与数据泄露
后端·github·api
wangbing11253 小时前
springboot应用关闭时触发动作
java·spring boot·后端
weixin_460443566 小时前
2026年新修订《网络安全法》实施:Java私有化考试系统如何做好SBOM、漏洞治理与安全升级?
java·开发语言·在线考试系统·企业培训考试系统·宏远培训考试系统·国企培训考试系统·国产化培训系统
子兮曰7 小时前
把 649 种文件格式塞进一个网页里:一个「文件不出浏览器」的预览器
前端·javascript·后端