Spring Boot 中嵌入式 Tomcat 的启动流程


🧠 一、Spring Boot 嵌入式 Tomcat 的核心设计

✅ 1. 嵌入式容器的抽象接口

Spring Boot 使用 WebServer 接口抽象嵌入式 Web 容器:

public interface WebServer {
    void start();
    void stop();
    int getPort();
}
  • Tomcat 实现TomcatWebServer
  • Jetty 实现JettyWebServer
  • Undertow 实现UndertowWebServer

✅ 2. Tomcat 容器的工厂类

TomcatServletWebServerFactory 是创建 TomcatWebServer 的核心类,它实现了 WebServerFactoryCustomizer 接口:

public class TomcatServletWebServerFactory extends AbstractServletWebServerFactory {
    public WebServer getWebServer(ServletContextInitializer... initializers) {
        return new TomcatWebServer(createContext(initializers));
    }

    protected TomcatEmbeddedServletContainer getContext(ServletContextInitializer... initializers) {
        Tomcat tomcat = new Tomcat();
        File baseDir = createTempDir("tomcat");
        tomcat.setBaseDir(baseDir.getAbsolutePath());
        tomcat.getHost().setAutoDeploy(false);
        configureEngine(tomcat.getEngine());
        return tomcat;
    }
}

🔄 二、Tomcat 启动流程详解

✅ 1. Spring Boot 应用启动入口

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

run() 方法中,Spring Boot 会调用 refresh() 方法,触发上下文刷新流程。


✅ 2. refresh() 方法中触发 Web Server 初始化

public void refresh() throws BeansException, IllegalStateException {
    try {
        // ...
        this.finishBeanFactoryInitialization(beanFactory);
        // ...
        finishRefresh();
    } catch (BeansException ex) {
        // ...
    }
}

protected void finishRefresh() {
    super.finishRefresh();
    webServer.start(); // 启动 Web Server
}

✅ 3. finishBeanFactoryInitialization() 中创建 Web Server

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // ...
    webServer = beanFactory.getBean(WebServer.class); // 获取 WebServer 实例
    // ...
}

📦 三、Web Server 的创建流程

✅ 1. TomcatServletWebServerFactory 创建 WebServer

@Bean
public WebServer webServer(TomcatServletWebServerFactory factory) {
    return factory.getWebServer(getServletContextInitializers());
}
核心方法:getWebServer()
public WebServer getWebServer(ServletContextInitializer... initializers) {
    Tomcat tomcat = new Tomcat();
    File baseDir = createTempDir("tomcat");
    tomcat.setBaseDir(baseDir.getAbsolutePath());
    tomcat.getHost().setAutoDeploy(false);
    configureEngine(tomcat.getEngine());

    // 创建 Context 并添加 ServletContextInitializer
    TomcatEmbeddedServletContainer container = createContext(tomcat, initializers);

    // 创建 WebServer
    return new TomcatWebServer(tomcat, container, isAutoStart());
}

✅ 2. TomcatWebServer 初始化与启动

public class TomcatWebServer implements WebServer {
    private final Tomcat tomcat;
    private final boolean autoStart;

    public TomcatWebServer(Tomcat tomcat, boolean autoStart) {
        this.tomcat = tomcat;
        this.autoStart = autoStart;
        initialize();
    }

    private void initialize() throws WebServerException {
        try {
            this.tomcat.start(); // 启动 Tomcat
        } catch (Exception ex) {
            throw new WebServerException("Unable to start embedded Tomcat", ex);
        }
    }
}

✅ 3. Tomcat 实例的创建与配置

(1)创建 Tomcat 实例
Tomcat tomcat = new Tomcat();
  • Tomcat 是 Apache Tomcat 的嵌入式 API 提供的类,用于创建和管理嵌入式 Tomcat 实例。
(2)设置 BaseDir
File baseDir = createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
  • 设置 Tomcat 的临时目录,用于存储 worklogs 等运行时文件。
(3)配置 Engine 和 Host
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
  • 关闭自动部署(避免冲突)
  • 设置 Engine 的基础配置(如日志路径、线程池等)
(4)创建 Context(Web 应用上下文)
protected TomcatEmbeddedServletContainer createContext(Tomcat tomcat, ServletContextInitializer... initializers) {
    StandardContext context = new StandardContext();
    context.setPath("");
    context.addLifecycleListener(new Tomcat.FixContextListener());
    context.setUseHttpOnly(true);

    for (ServletContextInitializer initializer : initializers) {
        initializer.onStartup(context); // 注册 ServletContextInitializer
    }

    tomcat.getHost().addChild(context);
    return context;
}

🧱 四、Servlet 初始化流程

✅ 1. ServletContextInitializer 的注册

Spring Boot 会收集所有 ServletContextInitializer 实现类(如 ServletRegistrationBean, FilterRegistrationBean),并注册到 Tomcat Context 中:

for (ServletContextInitializer initializer : initializers) {
    initializer.onStartup(context);
}
示例:注册 DispatcherServlet
@Bean
public ServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
    return new ServletRegistrationBean(dispatcherServlet, "/");
}

✅ 2. DispatcherServlet 的注册

DispatcherServlet 是 Spring MVC 的核心组件,由 DispatcherServletAutoConfiguration 自动注册:

public class DispatcherServletAutoConfiguration {
    @Bean
    public DispatcherServlet dispatcherServlet() {
        return new DispatcherServlet();
    }
}

🔄 五、Tomcat 的启动流程(tomcat.start()

✅ 1. Tomcat 的启动入口

tomcat.start(); // org.apache.catalina.startup.Tomcat

✅ 2. Tomcat 初始化阶段

(1)创建 Server 实例
Server server = new StandardServer();
  • StandardServer 是 Tomcat 的核心组件,代表整个 Tomcat 服务器。
(2)创建 Service 实例
Service service = new StandardService();
service.setName("SpringBootTomcat");
server.addService(service);
  • StandardService 是服务组件,包含 ConnectorEngine
(3)创建 Engine 实例
Engine engine = new StandardEngine();
engine.setDefaultHost("localhost");
service.setContainer(engine);
  • StandardEngine 是请求处理的核心组件。
(4)创建 Host 实例
Host host = new StandardHost();
host.setName("localhost");
engine.addChild(host);
  • StandardHost 表示虚拟主机。
(5)创建 Context 实例(Web 应用上下文)
Context context = new StandardContext();
context.setPath("");
context.setDocBase("");
host.addChild(context);
  • StandardContext 是 Web 应用的上下文。
(6)创建 Connector 实例(HTTP 连接器)
Connector connector = new Connector("HTTP/1.1");
connector.setPort(8080);
service.addConnector(connector);
  • Connector 负责监听 HTTP 请求。

✅ 2. 启动各组件

server.initialize();
server.start(); // 启动 Tomcat 服务器
  • initialize():初始化各组件(如加载 server.xmlweb.xml 等)
  • start():启动 Server、Service、Connector、Context 等组件

🧩 六、Tomcat 启动流程图(简化版)

Spring Boot run()
 └── refresh()
      └── finishBeanFactoryInitialization()
           └── getWebServer() → TomcatWebServer
                └── TomcatServletWebServerFactory.getWebServer()
                     └── new TomcatWebServer()
                          └── tomcat.start() → Tomcat 启动流程
                               └── StandardServer.initialize()
                               └── StandardServer.start()
                                    └── 启动 Engine、Host、Context、Connector

📦 七、Tomcat 启动的关键组件和作用

组件 作用
Tomcat Spring Boot 提供的嵌入式 Tomcat 工厂类
StandardServer Tomcat 服务器实例,管理整个生命周期
StandardService 服务组件,包含多个 Connector 和一个 Engine
StandardEngine 引擎组件,负责请求处理的核心流程
StandardHost 虚拟主机,管理多个 Context
StandardContext Web 应用上下文,管理 Servlet、Filter、Listener
StandardWrapper 封装 Servlet 实例,负责生命周期管理
Connector 监听 HTTP 请求,负责与客户端通信
ServletRegistrationBean 注册 Servlet 到 Tomcat Context
FilterRegistrationBean 注册 Filter 到 Tomcat Context

🧱 八、Tomcat 启动的完整流程

✅ 1. SpringApplication.run() 启动 Spring Boot 应用

public ConfigurableApplicationContext run(String... args) {
    ConfigurableApplicationContext context = null;
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        context = createApplicationContext();
        prepareContext(context, environment, applicationArguments);
        refreshContext(context);
    } catch (Throwable ex) {
        handleRunFailure(context, ex, listeners);
        throw new IllegalStateException(ex);
    }
    return context;
}

✅ 2. refresh() 阶段触发 Web Server 初始化

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    WebServer webServer = beanFactory.getBean(WebServer.class);
    webServer.start();
}

✅ 3. TomcatServletWebServerFactory 创建 Tomcat 实例

public WebServer getWebServer(ServletContextInitializer... initializers) {
    Tomcat tomcat = new Tomcat();
    File baseDir = createTempDir("tomcat");
    tomcat.setBaseDir(baseDir.getAbsolutePath());
    tomcat.getHost().setAutoDeploy(false);
    configureEngine(tomcat.getEngine());

    StandardContext context = createContext(tomcat, initializers);
    return new TomcatWebServer(tomcat, context, isAutoStart());
}

✅ 4. TomcatWebServer 启动 Tomcat

public class TomcatWebServer implements WebServer {
    private final Tomcat tomcat;
    private final boolean autoStart;

    public TomcatWebServer(Tomcat tomcat, boolean autoStart) {
        this.tomcat = tomcat;
        this.autoStart = autoStart;
        initialize();
    }

    private void initialize() throws WebServerException {
        try {
            this.tomcat.start(); // 启动 Tomcat 服务器
        } catch (Exception ex) {
            throw new WebServerException("Unable to start embedded Tomcat", ex);
        }
    }
}

✅ 5. Tomcat.start() 启动 Tomcat 服务器

public void start() throws LifecycleException {
    getServer().initialize();
    getServer().start();
}
StandardServer.initialize()
public void initialize() throws LifecycleException {
    if (initialized) return;
    lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
    this.initialized = true;
    this.lifecycle.fireLifecycleEvent(START_EVENT, null);

    // 初始化各组件(Engine、Host、Context、Connector)
    for (Service service : services) {
        service.start();
    }
}
StandardServer.start()
public void start() throws LifecycleException {
    // 启动 Engine、Host、Context
    for (Service service : services) {
        service.start();
    }

    // 启动 Connector(HTTP 服务器监听)
    for (Connector connector : connectors) {
        connector.start();
    }
}

🧪 九、Tomcat 启动的关键源码路径

类名 方法 说明
SpringApplication run() Spring Boot 应用启动入口
AbstractRefreshableWebApplicationContext refresh() 刷新上下文,触发 Web Server 启动
AbstractEmbeddedServletContainerFactory getWebServer() 创建嵌入式 Web Server
TomcatServletWebServerFactory getWebServer() 创建 Tomcat 实例
TomcatWebServer initialize() 初始化并启动 Tomcat
Tomcat start() 调用底层 Tomcat 的启动方法
StandardServer initialize() / start() Tomcat 的核心启动逻辑
StandardService start() 启动 Engine 和 Connector
StandardContext start() 加载 Servlet、Filter、Listener
StandardWrapper start() 初始化并启动 Servlet 实例
Connector start() 启动 HTTP 监听器

🧱 十、Tomcat 启动流程详解

✅ 1. Tomcat.start():启动 Tomcat 服务器

public void start() throws LifecycleException {
    getServer().initialize();
    getServer().start();
}
getServer().initialize()
public void initialize() throws LifecycleException {
    if (initialized) return;
    this.initialized = true;
    this.lifecycle.fireLifecycleEvent(START_EVENT, null);

    // 初始化 Engine、Host、Context、Connector
    for (Service service : services) {
        service.initialize();
    }
}
getServer().start()
public void start() throws LifecycleException {
    for (Service service : services) {
        service.start();
    }

    for (Connector connector : connectors) {
        connector.start(); // 启动 HTTP 监听器
    }
}

✅ 2. StandardService.start():启动 Engine 和 Connector

public void start() throws LifecycleException {
    if (this.engine != null) {
        this.engine.start(); // 启动 Engine
    }

    for (Connector connector : connectors) {
        connector.start(); // 启动 HTTP 服务器
    }
}

✅ 3. StandardEngine.start():启动 Engine

public void start() throws LifecycleException {
    // 加载 Host、Context
    for (Container child : children) {
        child.start();
    }
}

✅ 4. StandardContext.start():加载 Web 应用

public void start() throws LifecycleException {
    // 加载 Servlet、Filter、Listener
    for (LifecycleListener listener : lifecycleListeners) {
        listener.lifecycleEvent(new LifecycleEvent(this, Lifecycle.START_EVENT, null));
    }

    // 初始化 ServletContext
    fireLifecycleEvent(Lifecycle.CONFIGURE_START_EVENT, null);
}

✅ 5. StandardWrapper.start():初始化 Servlet

public void start() throws LifecycleException {
    // 调用 Servlet 的 init() 方法
    instance = loadServlet(servletClass);
    instance.init(new MockServletConfig());
}

✅ 6. Connector.start():启动 HTTP 服务器

public void start() throws LifecycleException {
    endpoint.start(); // 启动 NIO 或 BIO 线程池
    adapter = new CoyoteAdapter(this);
    protocolHandler.setAdapter(adapter); // 设置请求处理适配器
}

🧩 十一、Tomcat 启动的完整流程图(简化版)

Spring Boot run()
 └── refresh()
      └── finishBeanFactoryInitialization()
           └── getWebServer() → TomcatServletWebServerFactory.getWebServer()
                └── new TomcatWebServer()
                     └── tomcat.start()
                          └── StandardServer.initialize()
                               └── StandardService.initialize()
                                    └── StandardEngine.initialize()
                                         └── StandardHost.initialize()
                                              └── StandardContext.initialize()
                                                   └── StandardWrapper.initialize()
                          └── StandardServer.start()
                               └── StandardService.start()
                                    └── StandardEngine.start()
                                         └── StandardHost.start()
                                              └── StandardContext.start()
                                                   └── StandardWrapper.start()
                                                       └── DispatcherServlet.init()
                          └── Connector.start()
                               └── endpoint.start() → NIO 线程启动

📦 十二、Tomcat 启动的性能优化建议

优化点 说明
使用 NIO 连接器 默认使用 NIO,提升并发性能
调整线程池 通过 server.tomcat.max-threads 配置最大线程数
减少 Context 初始化耗时 通过 spring.boot.lazy-initialization=true 延迟加载非关键组件
启用 GZIP 压缩 server.tomcat.compress=true
配置连接池 使用 HikariCPTomcat JDBC Pool
关闭自动部署 tomcat.getHost().setAutoDeploy(false)
启用 APR/native 模式 使用 tomcat-native 提升性能(需安装 Native Lib)

✅ 十三、总结

特性 说明
默认容器 Spring Boot 默认使用嵌入式 Tomcat(spring-boot-starter-web
启动入口 SpringApplication.run()refresh()finishBeanFactoryInitialization()WebServer.start()
核心组件 StandardServerStandardServiceStandardEngineStandardHostStandardContextStandardWrapperConnector
Servlet 初始化 StandardWrapper.start()loadServlet()init()
HTTP 监听 Connector.start()endpoint.start() → NIO 线程池启动
性能优化 使用 NIO、延迟加载、GZIP 压缩、APR/native 模式
源码路径 org.apache.catalina.core.StandardContextorg.springframework.boot.web.embedded.tomcat.TomcatWebServer

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐