news 2026/7/29 3:15:43

SpringBoot 内嵌 Tomcat 的启动流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot 内嵌 Tomcat 的启动流程

Spring Boot 内嵌 Tomcat 的启动流程,本质上就是把“手动部署WAR包到外部Tomcat”这件事,变成通过Java代码在main方法里一键启动

整个流程拆成三大阶段,用最通俗的话讲透:


阶段一:SpringApplication 启动,触发自动配置

当你点击运行@SpringBootApplication的main方法时:

  1. SpringApplication.run()开始执行核心刷新(refresh)容器。

  2. Spring Boot的自动配置机制会扫描类路径,发现你依赖了spring-boot-starter-web,这会触发ServletWebServerFactoryAutoConfiguration配置类。

  3. 这个配置类会做一件事:创建一个内嵌Web服务器的工厂

    • 默认情况下,因为Tomcat的依赖存在,它会创建TomcatServletWebServerFactory

    • 这个工厂就是专门负责“生产”Tomcat服务器的。


阶段二:创建并配置 Tomcat 实例

这个阶段是整个流程的,它发生在refresh上下文时的onRefresh()方法里,具体步骤如下:

  1. 工厂开始构建TomcatServletWebServerFactorygetWebServer()方法被调用,此时会:

    • 实例化一个原生的org.apache.catalina.startup.Tomcat对象。

    • 设置基础目录(basedir),通常是操作系统的临时目录。

  2. 配置核心组件(Engine/Host/Context)

    • 创建Engine(引擎),默认名字叫"Tomcat"

    • 创建Host(虚拟主机),默认是localhost,并设置应用根目录。

    • 最关键的一步:创建Context(上下文)。这个Context代表你的整个Spring Boot应用,它的路径通常是空字符串""(即根路径)。

  3. 添加Servlet(即DispatcherServlet)

    • Spring Boot会创建一个DispatcherServlet的Bean。

    • 然后将这个Servlet动态添加到刚才创建的Context中,并映射到"/"(即所有请求)。

    • 注意:这里的添加并不是通过web.xml,而是通过编程方式调用Tomcat.addServlet()Context.addServletMapping()

  4. 设置端口和连接器

    • 读取你配置文件里的server.port(默认8080),设置到Tomcat的Connector(连接器)上。

    • 默认使用NIO协议org.apache.coyote.http11.Http11NioProtocol)。

此时,Tomcat实例已经构建完毕,但还没有启动,只是准备好了。


阶段三:启动 Tomcat 并发布 ServletContext

这是最后的点火动作:

  1. 触发启动:在refresh容器的最后一步(finishRefresh),会调用TomcatWebServerstart()方法。

  2. 内部启动链

    • 调用Tomcat.start()-> 这会启动所有组件(Connector、Engine、Host、Context)。

    • 连接器(Connector)开始监听指定端口,准备接收HTTP请求。

    • 同时,会触发ServletContextInitializer回调,执行你所有的FilterListener的初始化。

  3. 发布事件:启动成功后,Spring Boot会发布ServletWebServerInitializedEvent事件,表示内嵌服务器已就绪。

  4. 阻塞等待:最后,TomcatWebServer会启动一个非守护线程(keepAlive),让主线程阻塞,保证Tomcat一直运行,等待请求进来。


核心时序图

与外部Tomcat部署的关键区别(面试加分点)

对比维度外部Tomcat(传统WAR)Spring Boot 内嵌Tomcat
启动入口由Tomcat脚本(catalina.sh)触发由Java的main()方法触发
Servlet容器独立进程,部署多个WAR嵌入在JVM中,随应用启动和停止
Context创建方式解析web.xml或注解扫描编程式创建Context,并手动注册DispatcherServlet
类加载器复杂的委派机制(Common/Shared/Webapp)相对简单,直接使用应用类加载器(AppClassLoader)
适用场景多应用共享Tomcat微服务、云原生、独立运行
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/29 3:15:01

ST、NXP、英飞凌MCU选型实战指南:从内核到外设的决策逻辑

1. 项目概述:为什么需要一份MCU选型“速查手册”?干了这么多年嵌入式开发,手头用过的、评估过的、甚至只是简单了解过的微控制器(MCU)型号,少说也有上百款了。从最早的8位机到现在的多核Cortex-M/A系列&…

作者头像 李华
网站建设 2026/7/29 3:14:46

MATLAB .mat文件深度解析:从基础读写到跨平台数据交换实战

1. 项目概述:.mat文件与Matlab的深度绑定如果你在科研、工程或者数据分析领域工作,那么你几乎不可能绕过Matlab和它那个标志性的.mat文件。这个后缀为.mat的文件,就像是Matlab世界的“瑞士军刀”数据容器,它以一种高效、结构化的方…

作者头像 李华
网站建设 2026/7/29 3:14:29

Quartus调用Modelsim仿真失败全解析:从环境配置到波形调试

1. 从一次典型的仿真失败说起如果你正在用Quartus Prime配合Modelsim做FPGA或CPLD的仿真,大概率会遇到过这样的场景:在Quartus里点击“Run RTL Simulation”,满怀期待地等着波形窗口弹出,结果等来的却是一个冰冷的错误弹窗&#x…

作者头像 李华
网站建设 2026/7/29 3:14:21

如何用Sunshine打造家庭游戏串流服务器:从零开始的完整指南

如何用Sunshine打造家庭游戏串流服务器:从零开始的完整指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否厌倦了在不同设备间来回切换游戏?是否想在…

作者头像 李华
网站建设 2026/7/29 3:09:13

VS2022 C++ 单个项目如何开启管理员权限(完整指南)

VS2022 C 单个项目如何开启管理员权限(完整指南) 一、为什么需要管理员权限? 在 Windows 下,C 程序如果试图访问系统受保护目录(如 C:\Windows、C:\Program Files)、修改注册表或执行系统级操作&#xff…

作者头像 李华