Backend Development 10 min read

Understanding How Spring Boot Embeds Tomcat: A Source Code Walkthrough

This article explains how Spring Boot eliminates XML configuration and embeds servlet containers like Tomcat by analyzing Maven dependencies, core startup methods, WebServer creation, and the lifecycle methods that ultimately start and stop the embedded Tomcat instance.

Top Architecture Tech Stack
Top Architecture Tech Stack
Top Architecture Tech Stack
Understanding How Spring Boot Embeds Tomcat: A Source Code Walkthrough

Spring Boot simplifies Java web application development by allowing developers to package applications as executable JARs with an embedded servlet container, removing the need for external WAR deployment and XML configuration.

Before Spring Boot, a typical deployment required building a WAR file and deploying it to an external Tomcat or Jetty server. With Spring Boot, the Tomcat (or Jetty/Undertow) container is included as a library and started programmatically.

Tomcat‑embed Dependency

org.apache.tomcat.embed
tomcat-embed-core
${tomcat.version}

The SpringApplication.run() method triggers the bootstrapping process. The core of this process is the refresh() method, which ultimately creates and starts the embedded servlet container.

Creating the WebServer

protected void onRefresh() {
    super.onRefresh();
    createWebServer();
}

Inside createWebServer() , Spring Boot obtains a ServletWebServerFactory (e.g., TomcatServletWebServerFactory ) and calls its getWebServer() method.

Tomcat Instance Creation

public WebServer getWebServer(ServletContextInitializer... initializers) {
    Tomcat tomcat = new Tomcat();
    File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
    tomcat.setBaseDir(baseDir.getAbsolutePath());
    Connector connector = new Connector(this.protocol);
    tomcat.getService().addConnector(connector);
    tomcat.setConnector(connector);
    // configure host, engine, context, etc.
    return getTomcatWebServer(tomcat);
}

The TomcatWebServer constructor calls initialize() , which eventually invokes tomcat.start() and sets up lifecycle listeners.

Starting the Web Service

@Override
public void start() throws WebServerException {
    synchronized (this.monitor) {
        Connector connector = this.tomcat.getConnector();
        if (connector != null && this.autoStart) {
            performDeferredLoadOnStartup();
        }
        logger.info("Tomcat started on port(s): " + getPortsDescription(true) + " with context path '" + getContextPath() + "'");
    }
}

The performDeferredLoadOnStartup() method loads all servlet wrappers according to their loadOnStartup priority, completing the Tomcat startup sequence.

Integration with Spring Context

After the servlet container is started, ServletWebServerApplicationContext.finishRefresh() calls startWebServer() , which invokes webServer.start() (the Tomcat start shown above) and publishes a ServletWebServerInitializedEvent .

Summary

Spring Boot achieves embedded Tomcat by:

Including tomcat-embed-core as a Maven dependency.

Creating a TomcatServletWebServerFactory that builds a Tomcat instance.

Wrapping the Tomcat instance in TomcatWebServer , which handles initialization and lifecycle.

Triggering the start sequence during SpringApplication.run() via refresh() and finishRefresh() .

This design gives Spring Boot a clean, extensible backend architecture that can swap Tomcat for Jetty or Undertow with minimal code changes.

JavaBackend DevelopmentSpring Bootweb serverTomcatSource CodeEmbedded Server
Top Architecture Tech Stack
Written by

Top Architecture Tech Stack

Sharing Java and Python tech insights, with occasional practical development tool tips.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.