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
mainmethod that invokes
SpringApplication.run.
<code>@SpringBootApplication
public class TomcatdebugApplication {
public static void main(String[] args) {
SpringApplication.run(TomcatdebugApplication.class, args);
}
}
</code>The
runmethod creates a
ConfigurableApplicationContextand 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
<code>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);
}
</code>The method selects the appropriate context class based on
webApplicationType. For a typical Spring Boot web application, it instantiates
AnnotationConfigServletWebServerApplicationContext, which extends
ServletWebServerApplicationContextand ultimately
AbstractApplicationContext.
Refreshing the Context
<code>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();
}
</code>The
refreshcall 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
Tomcatinstance, configures a
Connector, and sets up the engine hierarchy.
<code>@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);
}
</code>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
Servercontains one or more
Serviceobjects; each Service holds an
Engineand one or more
Connectorinstances.
The diagram above shows the inheritance chain:
AnnotationConfigServletWebServerApplicationContext→
ServletWebServerApplicationContext→
AbstractApplicationContext.
Summary
Spring Boot starts by creating a
SpringApplicationinstance, which configures properties, publishes start events, prepares the environment, creates and refreshes the application context, and finally runs any
ApplicationRunneror
CommandLineRunner. The Tomcat startup occurs during the context refresh, where the embedded server is built, a
Connectoris added, and the container hierarchy (Engine → Host → Context → Wrapper) is initialized.
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.