How Spring Boot Boots Tomcat: Deep Dive into the Startup Process
This article explains how Spring Boot launches an embedded Tomcat server by tracing the main method, creating and refreshing the application context, and initializing Tomcat's core components such as connectors and containers, while detailing the hierarchy of Engine, Host, Context, and Wrapper.
Preface
Spring Boot offers a new development experience by allowing a web application to be packaged as a runnable JAR with an embedded container. This article uses Tomcat as an example to show how Spring Boot starts Tomcat and explores Tomcat's source code to understand its design.
Starting from the Main Method
Spring Boot applications begin with a main method that invokes SpringApplication.run.
@SpringBootApplication
public class TomcatdebugApplication {
public static void main(String[] args) {
SpringApplication.run(TomcatdebugApplication.class, args);
}
}The run method creates a ConfigurableApplicationContext and performs a series of steps, including configuring properties, publishing start events, initializing arguments, preparing the environment, creating the context, refreshing it, and finally publishing the running events.
Configure properties Obtain listeners and publish the start event Initialize input arguments Prepare environment and print banner Create application context Pre‑process the context Refresh the context Refresh the context again (extension point) Publish the started event Publish the running event
For Tomcat, the crucial steps are the creation of the application context ( createApplicationContext()) and its refresh ( refreshContext(context)).
Creating the Application Context
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}The method selects the appropriate context class based on webApplicationType. For a typical Spring Boot web application, it instantiates AnnotationConfigServletWebServerApplicationContext, which extends ServletWebServerApplicationContext and ultimately AbstractApplicationContext.
Refreshing the Context
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
} catch (AccessControlException ex) {
// ignored in restricted environments
}
}
}
protected void refresh(ApplicationContext applicationContext) {
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
((AbstractApplicationContext) applicationContext).refresh();
}The refresh call ultimately invokes AbstractApplicationContext.refresh(), which prepares the context, loads bean definitions, registers post‑processors, initializes special beans, and finally publishes the ContextRefreshedEvent.
Tomcat Internals
During the refresh, ServletWebServerApplicationContext.onRefresh() creates the embedded web server. The TomcatServletWebServerFactory.getWebServer() method builds a Tomcat instance, configures a Connector, and sets up the engine hierarchy.
@Override
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);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}The engine hierarchy consists of four container types:
Engine – the top‑level container.
Host – child of Engine, represents a virtual host.
Context – child of Host, corresponds to a servlet context (a web application).
Wrapper – child of Context, wraps an individual servlet.
Tomcat’s Server contains one or more Service objects; each Service holds an Engine and one or more Connector instances.
The diagram above shows the inheritance chain: AnnotationConfigServletWebServerApplicationContext → ServletWebServerApplicationContext → AbstractApplicationContext.
Summary
Spring Boot starts by creating a SpringApplication instance, which configures properties, publishes start events, prepares the environment, creates and refreshes the application context, and finally runs any ApplicationRunner or CommandLineRunner. The Tomcat startup occurs during the context refresh, where the embedded server is built, a Connector is added, and the container hierarchy (Engine → Host → Context → Wrapper) is initialized.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
