在Java生态中,Spring Boot凭借“自动配置+内嵌容器”的设计理念,彻底改变了传统Web应用的开发与部署方式。而小孩ai助手作为学习资源,可以帮助开发者更系统地掌握这类核心知识点——本文将深入剖析Spring Boot默认内置的Tomcat嵌入式Web服务器的实现原理、配置实战与底层技术,帮你彻底打通从“会用”到“懂原理”的最后一公里。
很多Java开发者都会遇到这样的困境:日常开发中用Spring Boot跑接口顺风顺水,但一旦面试被问到“Spring Boot是怎么启动Tomcat的?”“内嵌Tomcat和外部Tomcat有什么本质区别?”等问题时就哑口无言。本文将聚焦这一问题,从传统部署痛点出发,全面拆解Spring Boot内嵌Tomcat的设计思想与底层机制,并附上代码示例和高频面试题。

📌 最新版本提示:截至2026年4月,Spring Boot最新稳定版为4.0.5(2026年3月26日发布),同时维护3.5.13版本,Tomcat 11.0.21已于2026年4月8日发布,实现了Jakarta EE 11平台规范。
一、痛点切入:传统Web开发为什么这么“重”?

传统做法:手动部署WAR到外部Tomcat
回忆一下传统的Java Web开发流程:
在IDE中编写Servlet/JSP代码
编译打包生成WAR文件
将WAR文件拷贝到Tomcat的
webapps/目录启动Tomcat服务器(或重启已运行的Tomcat)
通过浏览器访问
http://localhost:8080/your-app/...
对应的项目结构通常还需要配置复杂的web.xml文件:
<!-- 传统web.xml配置示例 --> <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环境,换个环境就要重新配置
扩展性差:从单机到集群需要手动部署到每台机器的Tomcat,维护成本极高
开发效率低:每次修改代码都需要重新打包→部署→重启,反馈周期长
这正是Spring Boot内嵌Tomcat要解决的核心痛点——让应用自己携带运行环境,实现“写完代码,直接运行”。
二、核心概念讲解:什么是嵌入式Web服务器?
概念A:嵌入式Web服务器(Embedded Web Server)
定义:嵌入式Web服务器是指将Web容器的代码以依赖库的形式打包进应用程序中,应用启动时直接在JVM进程中创建并启动Web服务,无需外部独立部署。
关键词拆解:
嵌入式:不是独立的进程,而是应用程序的一部分
Web服务器:负责接收HTTP请求、调用业务逻辑、返回响应
一体化:应用JAR包 = 业务代码 + Web服务器 + 依赖环境
生活化类比:把传统方式想象成“要去饭店吃饭”——你需要先到饭店(启动Tomcat),然后再点菜(部署WAR)。而内嵌方式就像“叫外卖送到家”——饭菜和配送服务是一个整体,一次性交付。
概念B:Servlet容器
定义:Servlet容器是实现Jakarta Servlet规范(原Java Servlet规范)的Web服务器组件,负责管理Servlet的生命周期、处理HTTP请求映射、维护会话等。
与概念A的关系:Tomcat既是一个Servlet容器,也是Spring Boot默认的嵌入式Web服务器。嵌入式Web服务器是一种设计理念,而Servlet容器是这个理念的具体实现载体。
Tomcat 11版本速览(2026年4月最新)-22-21:
| 版本 | 实现规范 | JDK要求 | 核心变化 |
|---|---|---|---|
| Tomcat 9.x | Java EE 8 | JDK 8+ | 传统javax.包,2027年3月结束支持 |
| Tomcat 10.x | Jakarta EE 9/10 | JDK 8/11+ | 包名从javax.改为jakarta. |
| Tomcat 11.x | Jakarta EE 11 | JDK 17+ | 支持Servlet 6.0、Pages 4.0规范 |
⚠️ 重要提醒:从Tomcat 9升级到10/11时,API包名从javax.变更为jakarta.,代码需要适配修改,官方提供了迁移工具辅助升级。-22
三、概念关系与区别总结
嵌入式Web服务器 vs Servlet容器 vs Tomcat
| 概念层级 | 具体内容 | 一句话定位 |
|---|---|---|
| 设计思想 | 嵌入式Web服务器 | 应用自带运行环境,无需外部部署 |
| 实现载体 | Servlet容器 | 管理Servlet生命周期,处理HTTP请求映射 |
| 具体产品 | Apache Tomcat | 集以上两者于一身的开源实现 |
一句话记忆:Spring Boot用嵌入式的思想,通过Servlet容器规范,借助Tomcat这个具体产品,实现了“一行命令跑起整个Web应用”。
四、代码/流程示例演示
最简单的Spring Boot + 内嵌Tomcat示例
第一步:添加Maven依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>4.0.5</version> <!-- 2026年3月最新稳定版 --> </parent> <dependencies> <!-- 引入spring-boot-starter-web,自动传递引入内嵌Tomcat --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
💡 spring-boot-starter-web 会自动引入 spring-boot-starter-tomcat,其中包含了 tomcat-embed-core 等核心依赖。-70
第二步:编写启动类和Controller
@SpringBootApplication // 核心注解:组合了@Configuration + @EnableAutoConfiguration + @ComponentScan public class Application { public static void main(String[] args) { // 关键入口:触发整个启动流程,包括内嵌Tomcat的创建与启动 SpringApplication.run(Application.class, args); } } @RestController public class DemoController { @GetMapping("/hello") public String hello() { return "Hello, Embedded Tomcat!"; } }
第三步:一键运行
mvn spring-boot:run 或打包后直接运行 mvn clean package java -jar target/demo-1.0.jar
访问 http://localhost:8080/hello,即可看到返回结果。整个过程中,无需安装、配置或启动任何外部Tomcat。
自定义Tomcat配置(application.yml)
server: port: 9090 修改端口 tomcat: threads: max: 200 最大工作线程数(默认200) min-spare: 10 最小空闲线程数(默认10) accept-count: 100 等待队列长度(默认100) connection-timeout: 20000 连接超时时间(毫秒)
替换内嵌Web容器(Tomcat → Jetty)
<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-jetty</artifactId> </dependency>
📊 选择参考:Tomcat生态最完善、文档最丰富,适合绝大多数场景;Jetty更轻量、启动更快,适合微服务网关;Undertow并发性能更优,适合高吞吐量场景。-
五、底层原理/技术支撑
Spring Boot启动时内嵌Tomcat的创建与启动,核心依赖以下几个技术点:
核心流程
SpringApplication.run
refreshContext
刷新IOC容器
onRefresh钩子
模板方法模式
ServletWebServerApplicationContext
创建WebServer
TomcatServletWebServerFactory.getWebServer
创建Tomcat实例
设置端口/Connector/Context
Tomcat.start
启动内嵌服务器
关键代码路径-40
@SpringBootApplication中的@EnableAutoConfiguration触发自动配置扫描扫描
META-INF/spring.factories,加载ServletWebServerFactoryAutoConfiguration该配置类根据classpath中的依赖,实例化
TomcatServletWebServerFactorySpring容器刷新(
refreshContext)过程中,onRefresh()钩子调用ServletWebServerApplicationContext.createWebServer()调用
TomcatServletWebServerFactory.getWebServer()完成Tomcat的创建、配置和启动
底层依赖的技术基础
反射:Spring通过反射机制动态加载和实例化Tomcat相关类
SPI机制:
spring.factories本质是Java SPI思想的扩展实现模板方法模式:
AbstractApplicationContext.onRefresh()定义了扩展点,让子类实现具体逻辑事件/监听器:Spring通过ApplicationEvent和ApplicationListener实现容器生命周期与Tomcat生命周期的同步管理
💡 进阶提示:内嵌Tomcat的本质是在JVM进程中内嵌启动一个Servlet容器实例,这与传统独立Tomcat进程接收请求的架构有本质区别,但对上层的Servlet规范开发者来说是透明的。
六、高频面试题与参考答案
面试题1:Spring Boot 默认使用什么嵌入式Web容器?如何替换?
参考答案:
Spring Boot默认使用 Apache Tomcat 作为嵌入式Web容器
替换方法:在
pom.xml中排除spring-boot-starter-tomcat,引入spring-boot-starter-jetty或spring-boot-starter-undertow-49-70踩分点:Tomcat → Jetty/Undertow;通过starter机制自动装配
面试题2:Spring Boot 内嵌 Tomcat 的启动流程是怎样的?
参考答案(层次化记忆):
入口层:
SpringApplication.run()启动Spring容器刷新层:
refreshContext()触发容器刷新钩子层:
onRefresh()模板方法触发WebServer创建工厂层:
TomcatServletWebServerFactory.getWebServer()创建Tomcat实例启动层:调用Tomcat的
start()方法完成内嵌服务器启动-40
踩分点:按“入口→刷新→钩子→工厂→启动”五层递进回答,逻辑清晰
面试题3:内嵌Tomcat和外部独立Tomcat有什么区别?
| 对比维度 | 内嵌Tomcat | 外部独立Tomcat |
|---|---|---|
| 部署方式 | java -jar app.jar 一键运行 | 需安装Tomcat,手动部署WAR |
| 配置方式 | application.yml 或代码配置 | server.xml / context.xml |
| 环境隔离 | 每个应用独立的JVM进程 | 多应用共享Tomcat进程 |
| 适用场景 | 微服务、云原生、开发测试 | 传统单体应用、多应用共用服务器 |
踩分点:从部署方式、配置方式、环境隔离、适用场景四个维度对比回答
面试题4:Spring Boot 如何实现“约定大于配置”来内嵌Web容器?
参考答案:
spring-boot-starter-web自动引入Tomcat依赖,无需手动配置@EnableAutoConfiguration+spring.factories自动加载ServletWebServerFactoryAutoConfigurationServerProperties自动绑定application.yml中的配置一句话总结:通过依赖即配置 + 自动配置类扫描 + 属性绑定,实现了“引入依赖即拥有内嵌容器”的效果
踩分点:starter机制、自动配置类、属性绑定三者联动
七、总结
核心知识点回顾
什么是内嵌Web服务器:应用自带Web容器,无需外部部署
Tomcat的双重身份:既是Servlet容器,也是嵌入式Web服务器的具体实现
启动流程:Spring容器刷新 → onRefresh钩子 → WebServerFactory → Tomcat实例化与启动
底层支撑:反射、SPI机制、模板方法模式、事件监听
配置与替换:
application.yml灵活配置,starter机制支持无缝切换Jetty/Undertow
易错点提醒
❌ 不要手动
new Tomcat()—— 会绕过Spring的自动配置,失去AOP、事务等核心能力-70❌ 内嵌模式下没有
conf/server.xml文件,配置全部通过YAML或Java完成-70❌ 内嵌Tomcat不需要(也没有)
webapps目录,静态资源放在src/main/resources/static/下
进阶方向预告
下一篇将深入 Spring Boot WebFlux 响应式编程,讲解如何基于Netty实现非阻塞I/O,对比传统Servlet容器的线程模型差异,敬请期待。