发布时间:2026年4月10日
目标读者:技术入门/进阶学习者、在校学生、面试备考者、相关技术栈开发工程师
文章定位:技术科普 + 原理讲解 + 代码示例 + 面试要点
一、开篇引入:为什么每个Spring Boot开发者都要搞懂内嵌容器?

在Spring Boot出现之前,用Java开发Web应用,得先把代码打成WAR包,然后手动部署到外部的Tomcat或Jetty容器中,还得配置一堆xml文件。这不仅步骤繁琐,还容易出错——环境不一致、配置遗漏、启动失败,每个问题都够让人折腾半天。
「Spring Boot的嵌入式Web容器」 (Embedded Web Container),正是为解决上述痛点而生。它将Web服务器直接打包到应用程序中,让应用通过java -jar就能独立运行,无需任何外部容器。内嵌容器(Tomcat、Jetty、Undertow、Netty)是Spring Boot最核心的基础能力之一,也是面试中绕不开的高频考点。很多初学者只知道“能用”,一旦问到“Spring Boot怎么启动Tomcat”“Tomcat和Undertow有什么区别”“为什么Spring Boot 4移除了Undertow”就卡住了。

本文将从小花ai助手整理的资料出发,从痛点切入,带你理清嵌入式容器的核心概念、底层原理、选型对比和面试要点,帮你建立从概念到实战的完整知识链路。
二、痛点切入:为什么需要嵌入式容器?
2.1 传统方式的“四宗罪”
在嵌入式容器出现前,开发Web应用的标准流程是这样的:
<!-- web.xml 传统配置示例 --> <web-app> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-servlet.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
这个过程存在以下痛点:
环境耦合:开发环境装一个Tomcat,测试环境装一个Tomcat,生产环境还得单独部署一个容器。不同环境的版本差异往往导致“本地能跑,线上挂了”的窘境。
配置繁琐:每个项目都需要配置web.xml、server.xml等配置文件,重复劳动。
部署笨重:每次部署都需要停止容器、拷贝WAR包、重启容器,运维成本高。
扩展性差:做微服务拆分时,每个服务都需要一个独立的容器实例,资源浪费严重。
2.2 嵌入式容器如何破局?
Spring Boot在spring-boot-starter-web中默认内置了Tomcat作为嵌入式容器,应用直接打成JAR包,运行java -jar即可启动一个完整的Web服务器-7。这种“把服务器装在应用里”的做法,彻底解决了传统方式的痛点:
环境统一:容器版本和应用代码一起打包,不存在环境差异问题。
零配置:无需web.xml,Spring Boot自动配置。
一键部署:直接运行JAR包,无需额外操作。
云原生友好:非常适合Docker容器化部署和微服务架构。
三、核心概念讲解:什么是嵌入式Web容器?
3.1 定义拆解
嵌入式Web容器(Embedded Web Container),顾名思义,就是把Web服务器(如Tomcat)作为应用程序的一部分,嵌入在应用中运行,而不是单独部署一个外部服务器。
拆解关键词:
“嵌入式” :指容器与应用运行在同一个进程中,不需要额外的进程或环境。
“Web容器” :指实现了Servlet规范的服务器,负责接收HTTP请求、调用Servlet处理、返回响应。
3.2 生活化类比
想象一下传统方式和嵌入式容器的区别:
传统方式(外部容器) :像在商场里开一个档口,商场提供水电气等基础设施。但如果商场关门,档口就没办法营业了。这种模式依赖外部环境。
嵌入式方式 :像开一辆移动餐车,餐车自带发电机、水源和厨房设备,随时可以开出去做生意。无论走到哪里,餐车自身就能独立运行。
3.3 作用和价值
嵌入式容器的核心价值在于 “让Java Web应用变成独立运行的可执行程序” 。开发者不再关心外部容器的安装和配置,只需专注于业务逻辑。这种设计为微服务架构、容器化部署提供了天然支持,使Java应用能够像Node.js应用一样轻量快捷地运行。
四、关联概念讲解:四大嵌入式容器对比
Spring Boot提供了四种嵌入式Web容器,可分为Servlet容器和Reactive容器两类-6。
4.1 Tomcat(默认容器)
标准定义:Tomcat是Apache软件基金会的开源Servlet容器,实现了Servlet、JSP等Java Web技术规范,是Java Web开发中最常用的容器之一-30。
特点:
生态最成熟,文档和社区支持最完善
默认200个工作线程,适合大多数业务场景-50
功能全面,稳定性高
4.2 Jetty
标准定义:Jetty是Eclipse基金会开发的轻量级Servlet容器,以快速启动和低内存占用著称-30。
特点:
内存占用约50-80MB,比Tomcat轻量-37
启动速度比Tomcat快约30%
对长连接(WebSocket/SSE)支持更好
4.3 Undertow
标准定义:Undertow是Red Hat公司开发的高性能Servlet容器,基于NIO(非阻塞I/O)技术,具有低延迟和高吞吐量的特点-30。
特点:
吞吐量比Tomcat高50%以上-37
内存占用最低,约30-50MB
支持HTTP/2和WebSocket
4.4 Netty
标准定义:Netty是一个高性能的网络框架,在Spring Boot中作为Reactive Web应用的底层容器(通过spring-boot-starter-webflux启用)-6。
特点:
异步非阻塞模型
适合Reactive编程(Spring WebFlux)
不直接用于传统Servlet应用
五、概念关系与区别总结
四种容器的核心关系:
| 容器 | 适用场景 | 核心优势 | 内存占用 | 推荐指数 |
|---|---|---|---|---|
| Tomcat | 传统企业应用 | 生态完善、稳定可靠 | 约100MB+ | ⭐⭐⭐⭐⭐ |
| Jetty | 轻量级/嵌入式设备 | 启动快、长连接好 | 约50-80MB | ⭐⭐⭐⭐ |
| Undertow | 高并发API服务 | 吞吐量高、内存低 | 约30-50MB | ⭐⭐⭐⭐ |
| Netty | Reactive/WebFlux | 异步非阻塞 | 极低 | ⭐⭐⭐ |
一句话概括:Tomcat是“稳定可靠的大本营”,Jetty是“灵活轻便的随身工具”,Undertow是“性能狂魔的加速器”,Netty则是“响应式编程的新赛道”。
六、代码/流程示例:容器配置与切换实战
6.1 默认配置(Tomcat)
Spring Boot默认使用Tomcat,零配置即可启动:
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
在application.properties中配置容器参数:
端口配置 server.port=8080 server.servlet.context-path=/api Tomcat专属配置 server.tomcat.max-threads=200 server.tomcat.connection-timeout=30000
6.2 切换容器:从Tomcat到Jetty
在pom.xml中排除Tomcat,引入Jetty-7-30:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 排除默认的Tomcat依赖 --> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!-- 引入Jetty作为替代容器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> </dependencies>
6.3 切换容器:从Tomcat到Undertow
同样的方式,引入Undertow-7:
<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>
6.4 自定义容器配置
实现WebServerFactoryCustomizer接口进行精细化配置-5:
import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.stereotype.Component; @Component public class MyCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> { @Override public void customize(ConfigurableServletWebServerFactory factory) { factory.setPort(9090); // 设置端口 factory.setContextPath("/myapp"); // 设置上下文路径 factory.setSessionTimeout(30); // 设置会话超时(分钟) } }
6.5 容器启动原理图
SpringApplication.run() │ ▼ 创建 ServletWebServerApplicationContext (特殊的IoC容器) │ ▼ 执行 onRefresh() 方法 │ ▼ createWebServer() —— 调用 ServletWebServerFactory │ ├── TomcatServletWebServerFactory ├── JettyServletWebServerFactory └── UndertowServletWebServerFactory │ ▼ 容器启动完成,应用开始监听端口
七、底层原理/技术支撑点
7.1 核心依赖:ServletWebServerApplicationContext
Spring Boot内嵌容器的底层依赖一个特殊的IoC容器——ServletWebServerApplicationContext。这个容器在启动过程中会主动寻找ServletWebServerFactory(Servlet Web服务器工厂),调用它来创建和启动嵌入式Web服务器-5。
7.2 自动配置机制
ServletWebServerFactoryAutoConfiguration是关键的自动配置类。它会根据项目中实际引入的Web服务器包动态判断该创建哪个工厂实例:默认情况下引入spring-boot-starter-web后,会自动配置TomcatServletWebServerFactory-5。
7.3 反射与类加载
Spring Boot利用类加载机制扫描META-INF/spring.factories文件中的自动配置类,并通过反射动态实例化相应的容器工厂。例如,检测到类路径存在org.eclipse.jetty.server.Server时,才会激活Jetty的自动配置。
为什么要在文章中提及这些底层知识点?
本文以理解概念、掌握用法、应对面试为主。底层原理的完整源码分析(如onRefresh()如何调用createWebServer()、Tomcat.start()的具体实现)属于进阶内容,后续文章会单独深入讲解。了解上述定位,能让你对整个技术栈的脉络更清晰。
八、高频面试题与参考答案
8.1 Spring Boot支持哪些嵌入式Web容器?各自适用什么场景?
参考答案:Spring Boot支持Tomcat(默认)、Jetty、Undertow和Netty四种嵌入式Web容器-50。踩分点:能说出四种容器名称并简单区分。
Tomcat:生态最完善,适合大多数传统Web应用和Spring Boot项目,默认选项。
Jetty:轻量级,启动快、内存小,对WebSocket长连接支持更好,适合嵌入式场景。
Undertow:高性能、低内存、高吞吐量,基于NIO,适合高并发API服务和微服务场景。
Netty:异步非阻塞,适用于Spring WebFlux响应式编程。
8.2 Spring Boot内嵌容器的启动流程是怎样的?
参考答案:Spring Boot在启动时,通过SpringApplication.run()方法创建ServletWebServerApplicationContext,然后执行onRefresh()方法调用createWebServer()。createWebServer()会根据类路径中的依赖选择合适的ServletWebServerFactory(如TomcatServletWebServerFactory),创建并启动嵌入式服务器-5。踩分点:能讲出“工厂模式”+“自动配置”两个关键词。
8.3 如何在Spring Boot中从Tomcat切换到Undertow?
参考答案:在pom.xml中,将spring-boot-starter-web依赖下的spring-boot-starter-tomcat排除,然后添加spring-boot-starter-undertow依赖即可-60。踩分点:明确说出“排除Tomcat依赖→添加Undertow依赖”的步骤顺序。
<!-- 排除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>
8.4 Tomcat、Jetty、Undertow三者性能上有什么区别?
参考答案:在吞吐量方面,Undertow性能最优,比Tomcat高50%以上,在高并发场景下表现最为突出;Tomcat作为默认容器,性能均衡稳定,社区成熟度最高;Jetty启动速度最快,内存占用约50-80MB,适合资源受限的嵌入式场景和长连接服务-37。踩分点:能从“吞吐量/启动速度/内存占用”三个维度展开对比。
8.5 如何自定义嵌入式容器的配置(如端口、线程数)?
参考答案:有两种方式:一是直接在application.properties或application.yml中配置,如server.port=9090;二是实现WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>接口,在customize方法中设置端口、上下文路径等参数-5。踩分点:明确说出两种方式的区别——配置文件适合简单配置,Customizer适合复杂定制。
九、结尾总结
9.1 核心知识回顾
本文围绕Spring Boot嵌入式Web容器这一核心能力,系统梳理了以下要点:
嵌入式容器的定义:把Web服务器嵌入到应用中,让Java应用独立运行。
四大容器对比:Tomcat(默认/生态成熟)、Jetty(轻量/长连接)、Undertow(高性能/低内存)、Netty(响应式)。
切换配置方法:排除Tomcat依赖,引入Jetty或Undertow依赖即可。
底层原理:
ServletWebServerApplicationContext+ServletWebServerFactory工厂模式 + 自动配置。面试考点:容器类型、切换方法、性能差异、自定义配置。
9.2 重点提示与易错点
端口冲突:默认8080端口易被占用,务必检查或修改-7。
依赖排除遗漏:切换容器时忘记排除
spring-boot-starter-tomcat会导致多个容器共存,启动异常。容器配置优先级:代码中的
WebServerFactoryCustomizer优先级高于application.properties。
9.3 下一篇预告
下期将从源码层面深入剖析Spring Boot嵌入式容器的启动原理,带你一步步追踪onRefresh() → createWebServer() → Tomcat.start()的完整调用链路,从源码角度彻底搞懂内嵌容器的“黑魔法”。欢迎持续关注!
版权说明:本文基于小花ai助手整理的资料编写,旨在帮助开发者系统掌握Spring Boot嵌入式容器知识。如有疑问或建议,欢迎在评论区交流讨论。