当我们依赖 spring-boot-starter-web 在 main 方法中一键启动应用时,很少追问:一个 HTTP 请求到底是如何“飞”到 @RestController 里的?Spring Boot 只是帮我们内嵌了 Tomcat,但这背后是 Spring Boot 核心的 自动装配机制与 ServletWebServerFactory 设计思想的落地实践,也是面试中从“会用”到“懂原理”的分水岭知识点。本文通过痛点切入、概念拆解、代码演示与高频考题,帮你彻底理清 Spring Boot 内嵌 Web 容器的完整知识链路。
一、痛点切入:为什么需要内嵌容器?

传统 Web 开发的痛点:传统 Web 部署需先安装配置 Tomcat,生成 WAR 包放进 webapps 目录,启动外部服务器才能调试。开发环境与生产环境容器版本不一致可能导致诡异兼容性问题;多人协作时 IDE 配置各异,团队环境难统一;调试依赖远程部署,效率低下。
Spring Boot 的解决方案:内嵌 Web 容器(Embedded Web Server)允许直接把应用打包成可执行 JAR 文件,内含 Tomcat 等服务器,无需部署到单独容器中-。只需一条 java -jar app.jar 即可在任何有 JRE 的环境运行,彻底消灭“环境不一致”问题。

二、核心概念讲解:内嵌容器(Embedded Web Server)
英文全称:Embedded Web Server 中文释义:内嵌式 Web 服务器
拆解关键词:Embedded 意为嵌入,将原本独立安装的 Web 容器作为依赖库嵌入应用内部;Web Server 负责处理 HTTP 协议、管理 Servlet 生命周期、维护线程池等。内嵌容器本质是把 Tomcat/Jetty/Undertow 这类服务器的 JAR 包加入 classpath,在 Spring 容器启动过程中动态创建并启动服务器实例-。
生活化类比:传统部署像去餐馆吃饭——你准备好食材(代码),还得找一家有空位的厨房(外部容器)才能下锅;内嵌容器则像自带便携电磁炉——插上电就能开火,走到哪做到哪。
三、关联概念讲解:自动配置(Auto-Configuration)
英文全称:Auto-Configuration 中文释义:自动配置
标准定义:Spring Boot 根据项目 classpath 中的依赖、已定义的 Bean 以及各种属性设置,自动推断并配置应用所需的组件-31。核心是通过 @EnableAutoConfiguration 注解配合 spring.factories 文件,在启动时扫描并加载符合条件的配置类-13。
四、概念关系与区别总结
逻辑关系:自动配置是思想,内嵌容器是其具体实现之一。Spring Boot 扫描 classpath 发现有 spring-boot-starter-web 依赖,便自动配置 TomcatServletWebServerFactory,然后在容器刷新时创建并启动 Tomcat 实例。
一句话记忆:自动配置决定了用哪个容器,内嵌容器让应用变成“自带厨房的移动餐厅”。
五、代码示例:两种方式启动一个 Web 应用
方式一:传统方式(外部 Tomcat + WAR 包)
<!-- pom.xml 需要打包成 WAR --> <packaging>war</packaging> <!-- 还需要 web.xml 配置 Servlet --> <web-app> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
需安装外部 Tomcat、打包 WAR、复制到 webapps、启动外部服务器,操作繁琐且环境难统一。
方式二:Spring Boot 内嵌容器
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); // 一键启动 } }
只需引入 spring-boot-starter-web 依赖(内含 spring-boot-starter-tomcat),执行 main 方法即完成服务器启动-13。
application.yml 中可轻松配置内嵌 Tomcat server: port: 8081 修改端口 tomcat: threads: max: 800 最大工作线程数 min-spare: 100 最小空闲线程数 connection-timeout: 20000 连接超时时间(ms)
配置自动绑定到 ServerProperties,通过 TomcatServletWebServerFactory 生效-43-44。
执行流程解析:main 方法调用 SpringApplication.run() 进入启动流程。Spring 推断应用类型为 SERVLET 后创建 AnnotationConfigServletWebServerApplicationContext;容器刷新过程中触发 onRefresh() 钩子,调用 createWebServer() 从工厂获取 Tomcat 实例;TomcatServletWebServerFactory 解析配置并启动内嵌 Tomcat,完成服务器监听-13-35。
六、底层原理支撑点
内嵌容器底层依赖 Spring 容器生命周期钩子(onRefresh 模板方法)、条件注解(@ConditionalOnClass 判断 classpath 是否有 Tomcat 类)、工厂模式(TomcatServletWebServerFactory 等工厂类创建不同容器)以及 Tomcat 原生 API。最底层的 ServerSocket 监听 TCP 连接,Tomcat 将 HTTP 字节流解析为 ServletRequest 后交给 DispatcherServlet-11。
七、高频面试题与参考答案
1. Spring Boot 内嵌容器的启动原理是什么?
答题要点:SpringApplication.run 创建并刷新 ApplicationContext,刷新过程中调用 onRefresh() 钩子,获取 ServletWebServerFactory(自动配置已注册),调用 getWebServer 创建并启动内嵌 Web 服务器(如 Tomcat)。
2. Spring Boot 默认支持哪些内嵌 Web 容器?如何切换?
答题要点:支持 Tomcat(默认)、Jetty、Undertow。切换方式:在 pom.xml 中排除 spring-boot-starter-tomcat,添加 spring-boot-starter-jetty 或 spring-boot-starter-undertow-22-36。
3. 如何修改内嵌 Tomcat 的生产环境配置?
答题要点:在 application.yml 使用 server.tomcat. 配置项,或通过 TomcatServletWebServerFactory 定制化 Bean。高并发场景建议调整最大线程数、连接数和队列长度-44。
4. Spring Boot 3.x 与 4.0 在内嵌容器方面有何变化?
答题要点:Spring Boot 3.x 默认使用 Tomcat 10.1+(Jakarta EE 9+),迁移到 4.0 时必须确保生产环境的 Tomcat 版本兼容,否则可能出现运行时 Servlet 错误-41。
5. 为什么 Spring Boot 能做到“内嵌容器 + 一键启动”?
答题要点:核心是“约定优于配置” + “自动装配”。spring-boot-starter-web 引入 Tomcat 依赖,自动配置类检测后创建容器工厂,Spring 容器刷新时调用钩子创建并启动服务器-35。
八、结尾总结
回顾全文,核心知识点可归纳为:
内嵌容器:将 Web 服务器作为库嵌入应用,实现“一次打包,随处运行”。
自动配置:通过条件注解 + 工厂模式,自动选择合适的容器并完成配置。
启动流程:
SpringApplication.run()→ 创建上下文 → 刷新容器 →onRefresh()钩子 → 工厂创建并启动内嵌服务器。面试高频:内嵌容器原理、容器切换、生产配置优化、版本升级兼容性。
易错点:勿混淆“内嵌容器”与“自动配置”;Spring Boot 不直接处理 HTTP 协议,仍由 Tomcat 完成底层解析,Spring Boot 做的是封装和自动装配。
系列预告:下一篇我们将深入 ServletWebServerFactoryAutoConfiguration 源码,剖析条件注解如何决定最终采用哪个容器工厂,以及如何通过 WebServerFactoryCustomizer 实现精细化定制,欢迎持续关注!
最后更新时间:2026年4月10日。本文基于 Spring Boot 3.4.x / 4.0-M 版本撰写,实际使用时请以官方文档为准。
