Understanding SpringBoot Startup: From main() to Web Container Initialization
This article walks through the complete SpringBoot startup sequence, starting with the main method annotated with @SpringBootApplication, detailing the creation of SpringApplication, environment preparation, context initialization, bean loading, embedded web server setup, event publishing, and final readiness, with code examples and common pitfalls.
1. Startup Entry: main() Method
The entry point of a SpringBoot application is the main method in a class annotated with @SpringBootApplication. Although it looks like a single line of code, it triggers the entire startup process.
// Startup class
@SpringBootApplication
public class SpringBootDemoApplication {
public static void main(String[] args) {
// Core code: launch SpringBoot application
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}2. Core Entry: SpringApplication.run()
The whole startup flow begins with SpringApplication.run(). This method performs two core actions:
Create a SpringApplication instance, initializing core configuration such as application type detection, initializers, and listeners.
Invoke the overloaded run method to execute the detailed startup steps (environment preparation, context initialization, web container startup, etc.).
3. Source Code: SpringApplication Instance Creation
When SpringApplication.run() is called, the constructor of SpringApplication runs the following simplified logic:
public SpringApplication(Class<?>... primarySources) {
this(null, primarySources);
}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// Determine application type (WEB, REACTIVE, NONE)
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// Load built‑in initializers
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// Load built‑in listeners
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// Deduce the main application class
this.mainApplicationClass = deduceMainApplicationClass();
}4. Core Startup Process (run method)
The run method (simplified) performs eight key steps, each corresponding to a specific operation and event:
Start timer and publish ApplicationStartingEvent – the earliest event, before any context or environment is created.
Prepare environment – create an Environment object, load configuration sources (system properties, command‑line args, application.properties/yml, profiles), then publish ApplicationEnvironmentPreparedEvent.
Print banner – optional; can be disabled with spring.banner.enabled=false or customized via banner.txt.
Create and initialize ApplicationContext – choose the concrete context class based on the application type (e.g., AnnotationConfigServletWebServerApplicationContext for servlet apps) and inject environment, initializers, and listeners. After initialization, publish ApplicationContextInitializedEvent.
Refresh the context – scan for bean definitions ( @Component, @Service, etc.), instantiate non‑lazy beans, perform dependency injection, execute @PostConstruct methods, and initialize built‑in features (AOP, transaction management). Finally, publish ContextRefreshedEvent.
Start the web container – if the type is SERVLET or REACTIVE, obtain a ServletWebServerFactory (default TomcatServletWebServerFactory), create the container, configure parameters (port, context path), register DispatcherServlet, start the server, and publish ServletWebServerInitializedEvent.
Execute custom runners – beans implementing CommandLineRunner or ApplicationRunner run after the context is ready. CommandLineRunner receives raw String[] args, while ApplicationRunner receives an ApplicationArguments object for easier option handling.
Publish final events – ApplicationStartedEvent (all beans initialized, web server started) and ApplicationReadyEvent (application fully ready to accept requests). The timer stops and startup duration is logged.
5. Web Container Initialization (Tomcat Example)
For servlet applications, the embedded Tomcat container is created and started as follows:
Create Tomcat instance via TomcatServletWebServerFactory.
Configure the connector (default port 8080, configurable via server.port and server.tomcat.connector.*).
Create TomcatWebApplicationContext to link Spring's context with Tomcat.
Register DispatcherServlet with the container (default mapping "/").
Start Tomcat by calling start(), which binds the connector to the port and begins listening for HTTP requests.
Publish ServletWebServerInitializedEvent after successful startup.
private void finishRefresh() {
initLifecycleProcessor();
getLifecycleProcessor().onRefresh();
publishEvent(new ContextRefreshedEvent(this));
WebServer webServer = startWebServer();
if (webServer != null) {
publishEvent(new ServletWebServerInitializedEvent(webServer, this));
}
}6. Common Configuration and Failure Scenarios
Embedded container – SpringBoot embeds Tomcat, Jetty, or Undertow, eliminating the need for external deployment.
Port configuration – default 8080; can be changed with server.port. If the port is occupied, a BindException is thrown.
Container switching – exclude Tomcat and add Jetty or Undertow dependencies to replace the default container.
Typical startup failures – port conflict, SSL misconfiguration, dependency conflicts (e.g., both Tomcat and Jetty on the classpath), illegal port numbers.
7. Event‑Driven Mechanism
The startup process is driven by a series of internal events published in a fixed order:
ApplicationStartingEvent ApplicationEnvironmentPreparedEvent ApplicationContextInitializedEvent ContextRefreshedEvent ServletWebServerInitializedEvent ApplicationStartedEvent ApplicationReadyEvent8. Auto‑Configuration
Most of the above steps are automatically configured via @EnableAutoConfiguration, which is included in @SpringBootApplication. Spring scans
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importsto load classes such as ServletWebServerFactoryAutoConfiguration and WebMvcAutoConfiguration.
9. Application Context Layers
BootstrapContext – loads early configuration (e.g., external config server, encryption) before the main ApplicationContext.
ApplicationContext – the primary context that manages all beans, dependency injection, and event publishing during the application lifecycle.
Mastering this flow enables rapid diagnosis of startup errors (e.g., bean‑creation failures, environment loading issues) and prepares you for interview questions about SpringBoot's internal mechanics.
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 Tech Workshop
Focused on Java backend technologies, sharing fundamentals, multithreading, JVM, the Spring ecosystem, microservices, distributed systems, high concurrency, source‑code analysis, and practical experience. Continuously delivers high‑quality original content, interview guides, and learning roadmaps to help Java developers progress from beginner to advanced, enhancing technical skills and core competitiveness.
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.
