Spring Boot Startup Explained: From Main Method to Tomcat Launch
This article walks through the complete Spring Boot startup sequence, starting with the SpringApplication.run entry point, detailing the preparation, application context creation, and refresh phases, and shows how the embedded Tomcat server is instantiated and started, illustrated with code snippets and diagrams.
Introduction
Recently a developer was asked in an interview about the Spring Boot startup process and when the embedded web container (Tomcat, Jetty, Undertow, etc.) is loaded and how the switch happens. This article answers those questions by tracing the execution from the SpringApplication.run(EasyPaasAdminApplication.class, args) entry point down to the point where Tomcat is started.
Execution Overview
Typical Spring Boot applications start with a static call to SpringApplication.run:
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}The run method creates a new SpringApplication instance, prepares the environment, creates the application context, refreshes it, and finally starts the embedded web server.
Static helper that can be used to run a SpringApplication from the specified source using default settings.
After this call the framework builds an ApplicationContext and, during the refresh phase, launches the web server.
Three Main Phases
Preparation phase, ApplicationContext creation phase, Refresh phase.
Preparation phase : Spring Boot loads initial settings and creates the SpringApplication context. The core code is the run() method of SpringApplication, which invokes various initializers.
ApplicationContext creation phase : Spring Boot builds the application context (either a WebApplicationContext for web apps or a generic ApplicationContext). Auto‑configuration scans the classpath, loads application.properties, application.yml, and META-INF/spring.factories, and registers beans.
Refresh phase : Spring Boot refreshes the context, creates the embedded web server, loads configuration, and initializes components. The Tomcat server is started during this phase.
Core Source Analysis
2.1 Preparation Phase
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
} catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
} catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}This method creates a StopWatch to measure startup time, obtains run listeners, prepares the environment, creates the application context, refreshes it, and finally registers shutdown hooks.
2.2 ApplicationContext Creation Phase
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
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);
}
} catch (ClassNotFoundException ex) {
throw new IllegalStateException("Unable to create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}The method decides the concrete context class based on the application type (Servlet, Reactive, or none) and instantiates it.
2.3 Refresh Context Phase
protected void refreshContext(ConfigurableApplicationContext applicationContext) {
refresh(applicationContext);
if (this.registerShutdownHook) {
try {
applicationContext.registerShutdownHook();
} catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
}The refresh call triggers the core ApplicationContext refresh, which starts the context, runs initializers, listeners, and ultimately creates the embedded WebServer (Tomcat by default).
During refresh Spring iterates over initializers and listeners:
for (ApplicationContextInitializer<?> initializer : getInitializers()) {
initializer.initialize(applicationContext);
}
for (ApplicationListener<?> listener : getApplicationListeners()) {
if (listener instanceof SmartApplicationListener) {
SmartApplicationListener smart = (SmartApplicationListener) listener;
if (smart.supportsEventType(eventType) && smart.supportsSourceType(sourceType)) {
invokeListener(smart, event);
}
} else if (supportsEvent(listener, eventType)) {
invokeListener(listener, event);
}
}These steps complete the startup and launch the embedded Tomcat server.
Reference
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.spring-application
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.
Java High-Performance Architecture
Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.
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.
