Author
The Spring Boot Bootstrapping Sequence describes how a Spring Boot application starts—from calling main() to launching the embedded server and initializing all beans.
It explains the complete lifecycle Spring Boot executes before the application becomes ready to handle requests.
In short: Bootstrapping Sequence = How Spring Boot starts and prepares your application before it becomes ready to handle requests.
The Spring Boot Bootstrapping Sequence refers to the complete internal startup process that Spring Boot performs from the moment you run SpringApplication.run() until your application is fully initialized and ready to serve requests.
It includes:
This sequence is the heart of Spring Boot’s startup mechanism and explains how Spring Boot:
Spring Boot Bootstrapping Sequence describes how Spring Boot prepares the environment, loads configs, initializes the ApplicationContext, creates beans, and starts the embedded server.
main() MethodThe JVM runs your main class (with @SpringBootApplication) and calls:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
This single line triggers the entire Spring Boot startup lifecycle.
Spring Boot prepares the runtime environment:
Example
SpringApplication app = new SpringApplication(MyApplication.class);
app.run(args);
What happens?
Spring Boot registers built-in listeners such as:
ApplicationStartingEventApplicationEnvironmentPreparedEventApplicationPreparedEventApplicationReadyEventApplicationFailedEventThese listeners respond to lifecycle events during startup.
Example
Create your own listener:
@Component
public class MyListener implements ApplicationListener<ApplicationStartingEvent> {
@Override
public void onApplicationEvent(ApplicationStartingEvent event) {
System.out.println("Application is starting...");
}
}
Spring Boot builds a ConfigurableEnvironment.
Loads settings from:
application.properties / application.ymlapplication-dev.yml)All property sources are merged into one unified Environment.
Example
application.properties:
app.mode=production
server.port=9090
Output (startup logs):
Loaded property: server.port=9090
Loaded property: app.mode=production
The Spring Boot banner is displayed:
banner.txtDefault banner example
. ____ _ __ _ _
/\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\
( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\
\\\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\\__, | / / / /
=========|_|==============|___/=/_/_/_/
Custom banner:
spring.banner.location=banner.txt
Spring Boot chooses the correct context based on application type:
AnnotationConfigServletWebServerApplicationContextReactiveWebServerApplicationContextAnnotationConfigApplicationContextThis context manages:
Example: For a normal Spring Boot REST API → servlet context is created.
Spring scans for components:
@Component, @Service, @Repository, @Controller@Configuration & @Beanspring-boot-autoconfigure.jar)Example:
@Service
public class OrderService {}
Spring creates a BeanDefinition like:
➡ Still no objects created—only metadata loaded.
Spring Boot modifies configuration before creating beans:
Example
Your application.properties:
spring.datasource.url=jdbc:h2:mem:test
Environment processors read these properties and configure DataSource.
Example Post Processor:
public class MyEnvProcessor implements EnvironmentPostProcessor {
public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication app) {
System.out.println("Active Profiles: " + env.getActiveProfiles().length);
}
}
This is where all DI magic happens.
What happens inside Refresh?
Create all non-lazy beans
If lazy is false, Spring creates beans immediately.
Perform dependency injection
Constructor, Setter, Field injection:
@Autowired
private UserRepository repo;
Apply BeanPostProcessors
Create AOP proxies
Example:
@Transactional
public class PaymentService {}
Spring wraps it in a CGLIB proxy like:
PaymentService$$EnhancerBySpringCGLIB
Run lifecycle callbacks
@PostConstructafterPropertiesSet()➡ This is the phase where the application structure becomes fully functional.
Spring Boot automatically starts:
It creates and registers:
Example output:
Tomcat started on port 8080
➡ At this moment, your HTTP endpoints become active.
Runs after all beans are ready.
Examples:
CommandLineRunner
@Bean
CommandLineRunner runner() {
return args -> System.out.println("App started!");
}
ApplicationRunner
@Bean
ApplicationRunner appRunner() {
return args -> System.out.println("Runner executed!");
}
➡ Used for seeding data, preloading cache, checking connections, etc.
Spring publishes ApplicationReadyEvent.
You can listen:
@Component
public class ReadyListener implements ApplicationListener<ApplicationReadyEvent> {
public void onApplicationEvent(ApplicationReadyEvent e) {
System.out.println("Application is READY!");
}
}
➡ The app is 100% ready to serve requests.
Spring adds a JVM shutdown hook:
@PreDestroyDisposableBean.destroy()Example:
@PreDestroy
public void cleanUp() {
System.out.println("Releasing resources...");
}
➡ Ensures graceful and safe shutdown.
┌──────────────────────────┐
│ JVM Starts Application │
│ Calls main() Method │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ SpringApplication Created│
│ Loads Initializers & │
│ Lifecycle Listeners │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Load Application │
│ Listeners │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Prepare Environment │
│ (properties, YAML, env, │
│ system vars, CLI args) │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Print Banner │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│Create ApplicationContext │
│(Servlet/Reactive/Non-Web) │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Load Bean Definitions │
│ (@ComponentScan, @Bean, │
│ Auto-Configuration) │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Apply Env Post-Processors │
│ (Profiles, properties) │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Refresh ApplicationContext│
│ Create Beans, DI, AOP, │
│ PostConstruct callbacks │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Start Embedded Server │
│ (Tomcat/Jetty/Undertow) │
│ Register DispatcherServlet │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Run Startup Runners │
│ (CommandLineRunner, │
│ ApplicationRunner) │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Application Ready Event │
│ (App Fully Started) │
└─────────────┬────────────┘
│
▼
┌──────────────────────────┐
│ Register Shutdown Hook │
│ Graceful Shutdown on Stop │
└──────────────────────────┘
These examples show exactly what happens internally from:
main() →This is the complete internal working of a Spring Boot application.