What Exactly Happens During Spring Boot Startup? A Deep Dive
This article walks through the Spring Boot startup sequence, detailing how the @SpringBootApplication entry point creates a SpringApplication instance, prepares the environment, builds and refreshes the IoC container, runs ApplicationRunner/CommandLineRunner callbacks, and finally publishes the ApplicationReadyEvent.
Overview
Spring Boot simplifies configuration and auto‑configuration, but its startup performs a series of steps such as bean loading, environment preparation, and auto‑configuration registration.
Spring Boot startup process
1. Create SpringApplication instance
A typical entry class:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}The static run() method delegates to new SpringApplication(primarySources).run(args), creating the SpringApplication object, setting command‑line arguments, and preparing for subsequent phases.
2. Prepare application context
During construction of SpringApplication ( new SpringApplication(primarySources)) the framework:
Determines the web application type by checking the classpath for classes such as DispatcherServlet to decide between Servlet, Reactive, or CLI.
Loads initializers by instantiating all ApplicationContextInitializer entries declared in META-INF/spring.factories.
Loads listeners by instantiating all ApplicationListener entries declared in META-INF/spring.factories.
After the SpringApplication object is built, its #run() method executes the core startup logic.
3. Environment preparation – loading configuration files
Spring Boot reads external configuration files ( application.properties or application.yml) and converts them into a ConfigurableEnvironment. Key steps:
Create or obtain a StandardEnvironment instance.
Parse application.yml and application.properties into property sources.
Publish an environment‑prepared event via listeners.environmentPrepared().
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
// Create and configure the environment
ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
listeners.environmentPrepared(bootstrapContext, environment);
DefaultPropertiesPropertySource.moveToEnd(environment);
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
EnvironmentConverter environmentConverter = new EnvironmentConverter(getClassLoader());
environment = environmentConverter.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
}
ConfigurationPropertySources.attach(environment);
return environment;
}4. Create and refresh the IOC container
4.1 Create the ApplicationContext
The core IOC container is an ApplicationContext. Depending on the detected web type, Spring Boot instantiates a concrete subclass such as AnnotationConfigServletWebServerApplicationContext:
private ConfigurableApplicationContext createApplicationContext() {
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(this.applicationContextClass);
}Creation steps:
Determine the context class based on the web type.
Instantiate the context via reflection.
Inject the prepared Environment into the context.
4.2 Refresh the IOC container
The refresh() method defined in AbstractApplicationContext performs eight sub‑steps:
public void refresh() throws BeansException, IllegalStateException {
// 1. Prepare context environment
prepareRefresh();
// 2. Create BeanFactory and load bean definitions
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. Initialize BeanFactory
prepareBeanFactory(beanFactory);
// 4. Register BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 5. Initialize MessageSource, event multicaster, etc.
initMessageSource();
initApplicationEventMulticaster();
// 6. Register listeners and publish early events
registerListeners();
// 7. Initialize all non‑lazy singleton beans
finishBeanFactoryInitialization(beanFactory);
// 8. Complete refresh
finishRefresh();
}This sequence loads bean definitions, registers post‑processors, initializes core infrastructure, registers listeners, and finally instantiates all singleton beans.
5. Execute initialization callbacks
After the container is refreshed, Spring Boot invokes ApplicationRunner and CommandLineRunner beans:
private 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());
for (Object runner : runners) {
if (runner instanceof ApplicationRunner) {
((ApplicationRunner) runner).run(args);
} else if (runner instanceof CommandLineRunner) {
((CommandLineRunner) runner).run(args.getSourceArgs());
}
}
}These callbacks are typically used for cache pre‑loading, task scheduling, or other post‑startup logic.
6. Startup completion event
When all initialization work finishes, Spring Boot publishes an ApplicationReadyEvent to signal that the application is fully started. Listeners can react to this event, for example, to register monitoring components.
listeners.running(context);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.
Shepherd Advanced Notes
Dedicated to sharing advanced Java technical insights, daily work snippets, and the power of persistent effort.
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.
