Spring Boot Startup Process Explained
Entry Point
java@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Startup Process Overview
shellSpringApplication.run() ├── 1. Create SpringApplication Instance │ ├── Deduce application type (Servlet/Reactive/None) │ ├── Load BootstrapRegistryInitializer │ ├── Load ApplicationContextInitializer │ └── Load ApplicationListener │ └── 2. Execute run() Method ├── 2.1 Start timer ├── 2.2 Create DefaultBootstrapContext ├── 2.3 Configure headless mode ├── 2.4 Publish Starting event ├── 2.5 Prepare Environment ├── 2.6 Print Banner ├── 2.7 Create ApplicationContext ├── 2.8 Prepare ApplicationContext ├── 2.9 Refresh ApplicationContext ├── 2.10 Execute Runners └── 2.11 Publish Started event
Detailed Startup Steps
Step 1: Create SpringApplication Instance
javapublic SpringApplication(Class<?>... primarySources) { this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); // Deduce application type this.webApplicationType = WebApplicationType.deduceFromClasspath(); // Load initializers and listeners this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories(); setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }
Application Type Deduction:
javastatic WebApplicationType deduceFromClasspath() { if (ClassUtils.isPresent(REACTIVE_WEB_ENVIRONMENT_CLASS, null) && !ClassUtils.isPresent(MVC_WEB_ENVIRONMENT_CLASS, null)) { return WebApplicationType.REACTIVE; } for (String className : SERVLET_INDICATOR_CLASSES) { if (ClassUtils.isPresent(className, null)) { return WebApplicationType.SERVLET; } } return WebApplicationType.NONE; }
Step 2: Execute run() Method Core Flow
javapublic ConfigurableApplicationContext run(String... args) { // Start timer StartupStep startupStep = this.applicationStartup.start("spring.boot.application.starting"); // Create BootstrapContext DefaultBootstrapContext bootstrapContext = createBootstrapContext(); // Get listeners and start SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(bootstrapContext, this.mainApplicationClass); try { // Prepare Environment ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments); // Print Banner Banner printedBanner = printBanner(environment); // Create ApplicationContext context = createApplicationContext(); // Prepare and Refresh Context prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); // Execute Runners callRunners(context, applicationArguments); listeners.running(context); } return context; }
Step 3: Prepare Environment
Configuration File Loading Order (high to low priority):
- Command line arguments
- JNDI properties from
java:comp/env - Java System properties
- OS environment variables
RandomValuePropertySource- External
application-{profile}.properties - Internal
application-{profile}.properties - External
application.properties - Internal
application.properties - @PropertySource annotations
- Default properties
Step 4: Refresh ApplicationContext (Core)
java@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 1. Prepare refresh prepareRefresh(); // 2. Obtain BeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 3. Prepare BeanFactory prepareBeanFactory(beanFactory); try { // 4. Post-process BeanFactory postProcessBeanFactory(beanFactory); // 5. Invoke BeanFactoryPostProcessors invokeBeanFactoryPostProcessors(beanFactory); // 6. Register BeanPostProcessors registerBeanPostProcessors(beanFactory); // 7. Initialize MessageSource initMessageSource(); // 8. Initialize Event Multicaster initApplicationEventMulticaster(); // 9. Initialize WebServer (subclass extension) onRefresh(); // 10. Register Listeners registerListeners(); // 11. Instantiate singleton beans finishBeanFactoryInitialization(beanFactory); // 12. Finish refresh finishRefresh(); } } }
WebServer Startup:
java@Override protected void onRefresh() { super.onRefresh(); try { // Create and start WebServer (Tomcat/Jetty/Undertow) createWebServer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start web server", ex); } }
Step 5: Execute Runners
javaprivate void callRunners(ApplicationContext context, ApplicationArguments args) { List<Object> runners = new ArrayList<>(); runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); AnnotationAwareOrderComparator.sort(runners); for (Object runner : runners) { if (runner instanceof ApplicationRunner) { callRunner((ApplicationRunner) runner, args); } if (runner instanceof CommandLineRunner) { callRunner((CommandLineRunner) runner, args); } } }
Startup Events
| Event | Trigger Timing |
|---|---|
ApplicationStartingEvent | When run method starts |
ApplicationEnvironmentPreparedEvent | When Environment is ready |
ApplicationContextInitializedEvent | When Context is initialized |
ApplicationPreparedEvent | When Context is prepared |
ApplicationStartedEvent | When Context refresh completes |
ApplicationReadyEvent | When all Runners complete |
ApplicationFailedEvent | When startup fails |
Summary
Spring Boot startup process can be summarized as:
- Instantiation Phase: Deduce app type, load initializers and listeners
- Environment Preparation: Prepare Environment, load config files
- Context Creation: Create and configure ApplicationContext
- Refresh Phase: Load bean definitions, initialize beans, start WebServer
- Completion Phase: Execute Runners, publish completion events
Understanding the startup process helps troubleshoot startup issues, customize startup logic, and optimize startup performance.