一、背景介绍:为什么需要内置 Web 容器?
在传统的 Java Web 开发中,我们需要将应用打包成 WAR 文件并部署到外部的 Servlet 容器(如 Tomcat、Jetty)中。这种方式存在几个明显缺点:
部署复杂度高:需要额外安装和配置 Web 服务器环境依赖性强:不同环境可能存在配置差异启动速度慢:需要先启动外部容器再加载应用资源利用率低:每个应用都需要独立的容器实例
Spring Boot 彻底改变了这一模式,通过内嵌 Web 容器技术,将 Web 服务器直接集成到应用中,实现了"开箱即用"的轻量级部署体验。这种设计带来了诸多优势:
简化部署:只需一个可执行 JAR 文件,内含所有依赖独立运行:应用自带服务器,无需额外安装快速启动:启动时间大幅缩短云原生友好:完美适配容器化部署和微服务架构资源高效:特别适合资源受限的环境
二、Spring Boot 支持的内置 Web 容器类型
Spring Boot 3.x 及之前版本提供了多种内置 Web 容器选择,每种都有其独特特性和适用场景:
1. Tomcat(默认容器)
特点:
Spring Boot 3.x 默认集成 Tomcat 10.x成熟的线程池管理机制(MaxThreads 默认 200)支持 HTTP/2 协议(需配合 SSL 配置)相对较低的内存占用(基础运行时约 30MB)广泛的社区支持和文档资源
适用场景:
传统 Java Web 应用需要稳定性和社区支持的项目与旧系统集成的场景
2. Jetty
特点:
轻量级和高并发处理能力启动时间比 Tomcat 快约 20%长连接应用支持优秀(如 WebSocket)嵌入式系统友好(资源占用比 Tomcat 低 15-20%)支持异步 IO 处理模型
适用场景:
需要快速启动的微服务长连接应用(WebSocket 等)边缘计算和资源受限环境
3. Undertow(Spring Boot 4 将不再支持)
重要通知:Spring Boot 4.0.0 M2 版本已正式移除对 Undertow 的支持!这一决定主要基于以下原因:
兼容性问题:Spring Boot 4.0 要求 Servlet 6.1 基线,而 Undertow 尚不兼容该规范维护问题:红帽公司对 Undertow 的更新不够积极,导致与 Spring Boot 的同步出现困难安全考虑:Tomcat 拥有更成熟的漏洞修复机制和更丰富的安全功能
Undertow 原有特点(供历史参考):
基于 NIO 的高性能容器内存占用最低(比 Tomcat 少 25% 左右)支持阻塞和非阻塞两种处理模型高吞吐量场景表现优异(每秒请求处理能力比 Tomcat 高 30%)灵活的 Handler 链机制
重要提醒:如果您的项目当前使用 Undertow,建议尽快迁移到 Tomcat 或 Jetty。对于高并发需求,Tomcat 10.1.x 和 Jetty 12.x 都提供了优秀的性能表现和更好的长期支持。
4. Netty(响应式专用)
特点:
事件驱动的非阻塞架构极致的性能表现(可处理百万级并发连接)支持多种协议(HTTP/1.x、HTTP/2、WebSocket)不直接支持 Servlet 规范,需配合 Spring WebFlux 使用
适用场景:
构建实时通信应用高并发响应式应用(如消息推送、实时数据分析)需要处理海量并发请求的场景
三、使用 Maven (pom.xml) 集成内置 Web 容器
Spring Boot 通过 Maven 的依赖管理机制简化了 Web 容器的集成过程。以下是详细的集成方法:
1. 基础项目结构
首先确保您的 pom.xml 包含 Spring Boot 的基础配置:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2. 集成不同 Web 容器的具体方法
方法一:使用默认 Tomcat(无需额外配置)
Spring Boot 的 spring-boot-starter-web 默认已经包含了 Tomcat 依赖,所以如果您只需要使用 Tomcat(Spring Boot 3.x 和 4.x 都支持),您不需要做任何额外配置:
方法二:切换到 Jetty 容器
如果您想使用 Jetty 替代默认的 Tomcat,需要:
排除 Tomcat 依赖添加 Jetty 依赖
具体配置如下:
方法三:使用 Netty(响应式编程)
对于 响应式编程 场景,您需要使用 Netty 作为底层服务器,通过 spring-boot-starter-webflux 实现:
重要说明:Netty 不是传统的 Servlet 容器,它基于 Reactor 响应式流规范,不兼容 Servlet API。因此,它只能用于 Spring WebFlux 响应式应用,不能用于传统的 Spring MVC 应用。
方法四:Spring Boot 4 用户特别注意(不再支持 Undertow)
对于 Spring Boot 4.0 及以上版本,如果您的项目需要高性能容器,只能选择 Tomcat 或 Jetty,因为:
Undertow 已被官方移除:Spring Boot 4.0.0 M2 版本已正式移除对 Undertow 的支持原因:Servlet 6.1 兼容性问题 + 维护支持不足
Spring Boot 4.x 用户的替代方案:
3. 容器配置参数(application.properties/yml)
无论使用哪种容器,您都可以通过配置文件调整服务器参数:
# 通用配置
server.port=8080 # 服务器端口
server.address=0.0.0.0 # 监听地址
# Tomcat 特定配置
server.tomcat.max-threads=200 # 最大线程数
server.tomcat.max-connections=10000 # 最大连接数
server.tomcat.connection-timeout=5000 # 连接超时时间(ms)
# Jetty 特定配置
server.jetty.threads.max=200 # 最大线程数
server.jetty.threads.min=10 # 最小线程数
# Undertow 特定配置(Spring Boot 3.x 及之前版本)
# server.undertow.buffer-size=1024
# server.undertow.threads.worker=200
# server.undertow.threads.io=10
四、实战:如何切换内置 Web 容器
1. 完整切换流程(以 Tomcat → Jetty 为例)
步骤 1:修改 pom.xml
步骤 2:清理并重新构建项目
# 清理旧构建
mvn clean
# 重新构建项目(会下载新的依赖)
mvn package
# 运行应用
mvn spring-boot:run
步骤 3:验证容器类型
启动应用后,观察控制台日志输出。您会看到类似以下信息:
Tomcat:Tomcat initialized with port(s): 8080Jetty:Jetty started on port(s) 8080Undertow:Started Undertow server at ... (Spring Boot 4 已不再显示)
2. 通过代码验证当前使用的容器
您可以在应用中添加以下代码来验证当前使用的 Web 服务器类型:
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class WebServerChecker {
@Bean
public ServletWebServerFactory servletWebServerFactory() {
// 这里实际上是由 Spring Boot 自动配置的
// 我们只是通过类型检查来确认使用的是哪个容器
return null;
}
// 或者在启动类中添加检查逻辑
public static void checkWebServerType() {
String serverInfo = org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.class
.cast(org.springframework.context.ApplicationContextProvider.getApplicationContext())
.getWebServer()
.getClass()
.getName();
System.out.println("当前使用的 Web 服务器: " + serverInfo);
if (serverInfo.contains("Tomcat")) {
System.out.println("✓ 使用的是 Tomcat 容器");
} else if (serverInfo.contains("Jetty")) {
System.out.println("✓ 使用的是 Jetty 容器");
} else if (serverInfo.contains("Undertow")) {
System.out.println("✓ 使用的是 Undertow 容器");
} else {
System.out.println("未知的 Web 服务器类型: " + serverInfo);
}
}
}
五、最佳实践与选择建议
1. 容器选择决策树
是否需要响应式编程 (WebFlux)?
├── 是 → 使用 Netty (通过 spring-boot-starter-webflux)
└── 否 → 传统 MVC 应用
├── 需要最高稳定性和最广泛支持? → 选择 Tomcat
├── 需要快速启动和低内存占用? → 选择 Jetty
└── 使用 Spring Boot 4? → 只能选择 Tomcat 或 Jetty (Undertow 已移除)
2. 各容器适用场景总结
容器适用场景优势Spring Boot 4 支持情况Tomcat传统 Web 应用、企业级应用、需要稳定性和广泛社区支持成熟稳定、功能完整、文档丰富、安全更新及时✅ 完全支持 (推荐)Jetty微服务、云原生应用、资源受限环境、需要快速启动启动快、内存占用低、长连接支持好✅ 完全支持 (推荐替代方案)Undertow高并发 API、需要极致性能的微服务高吞吐量、低内存占用、异步 I/O 性能优异❌ Spring Boot 4 已移除支持Netty响应式编程、实时数据流、超高并发事件驱动、非阻塞 I/O、百万级并发能力✅ 通过 WebFlux 支持
3. Spring Boot 4 用户特别建议
立即停止使用 Undertow:如果您的项目计划升级到 Spring Boot 4,或者已经是 Spring Boot 4 用户,请不要使用 Undertow,因为它已被官方移除。
评估迁移需求:
如果您当前使用 Undertow 是因为性能考虑,Tomcat 10.1.x 和 Jetty 12.x 都提供了优秀的性能如果是因为内存占用,Jetty 是比 Undertow 更可持续的选择
长期支持考虑:Tomcat 和 Jetty 都有更活跃的社区和更稳定的长期支持计划,是更可靠的选择。
六、总结
Spring Boot 的内置 Web 容器技术极大地简化了 Java Web 应用的部署和开发过程。通过本文的介绍,您应该已经了解:
内置 Web 容器的核心价值:简化部署、独立运行、快速启动各种容器的特性和适用场景:Tomcat 的稳定性、Jetty 的轻量级、Netty 的高性能通过 Maven pom.xml 集成不同容器的方法:排除默认依赖、添加目标容器依赖Spring Boot 4 的重要变更:不再支持 Undertow,必须迁移到 Tomcat 或 Jetty
推荐实践:
对于大多数项目,继续使用默认的 Tomcat 是最稳妥的选择如果需要更快的启动速度和更低的内存占用,选择 Jetty对于响应式编程项目,使用 WebFlux + NettySpring Boot 4 用户请避免使用 Undertow,并做好相应的迁移准备
通过合理选择和配置内置 Web 容器,您可以构建出更高效、更易于部署和管理的现代化 Java Web 应用。