Free tools Windows power users keep installed
One-click scans. No signup required.
When your code calls SpringApplication.run, Spring Boot does not build the application’s container in one step. It runs an orchestration sequence: it prepares the environment, creates an ApplicationContext of the right kind, runs initializers, loads your sources and bean definitions, refreshes the context, and then starts runners and signals readiness. In this article, “container” means the Spring ApplicationContext, not a Docker container image.
Three things that are easy to conflate
Most confusion about Boot startup comes from treating three different things as one. Keeping them apart makes the rest of the sequence easier to follow.
As an Amazon Associate I earn from qualifying purchases.
SpringApplicationis the coordinator. It is the Boot class that receives your sources and arguments, decides what to build, and fires lifecycle events at fixed points. It is documented in the SpringApplication reference.- The
ApplicationContextis the configured Spring container. It holds the beans and configuration that make up most of the application’s internal state.SpringApplicationcreates it, feeds it configuration, and refreshes it. It is not the coordinator. - Startup milestones are separate signals. Loading bean definitions, refreshing the context, being “live,” and accepting traffic are different points in time. A later section compares them directly.
How the startup sequence runs
The lifecycle is a consistent sequence at the level of Boot’s documented events and steps. The exact method calls inside SpringApplication change between releases, so treat the order below as the public lifecycle, not as a line-by-line trace of one version’s code.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →1. Bootstrap and environment preparation
A Java main method commonly delegates to SpringApplication.run:
#1 Best Overall
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Before any context exists, Boot builds the environment. Command-line arguments such as --server.port=8081 are exposed as properties in that environment. Once the environment is known, Boot publishes ApplicationEnvironmentPreparedEvent, still before the context is created. Because no context exists yet, a listener that must receive this event has to be registered on the SpringApplication or SpringApplicationBuilder itself. It cannot be declared as a bean in the context, since the context is not there to host it. The SpringApplication API documents this registration path.
2. Choosing and creating the context
Next, Boot creates the context. The choice depends on the application’s web type, and the creation step is delegated to a strategy interface, ApplicationContextFactory. The default implementation selects a context suited to the web application type. You can supply your own factory on SpringApplication. The contract is described in the ApplicationContextFactory API (Boot 3.0.0 page). The rest of the section below explains which context types exist and when a custom factory is worth considering.
3. Initializers and ApplicationContextInitializedEvent
Once the context exists, any ApplicationContextInitializer instances run. They run before bean definitions are loaded, so they are the place for early adjustments to the context itself. After the initializers finish, Boot publishes ApplicationContextInitializedEvent. This event marks the boundary between “context created and customized” and “definitions about to be read.” It is the stage where you can still change how the context is prepared before your configuration arrives.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errors4. Loading sources and bean definitions
The primary source is commonly the class annotated with @SpringBootApplication. The SpringApplication API treats application sources as the inputs from which the context’s bean definitions are read. That annotation also opts the application into auto-configuration, covered in its own section below. The result of this stage is a set of bean definitions. Those definitions are not yet live objects; they become beans when the context is refreshed.
Rank #2
5. ApplicationPreparedEvent and refresh
Boot publishes ApplicationPreparedEvent after bean definitions have been loaded and just before refresh starts. The official Spring Boot reference states the boundary directly:
“An
ApplicationPreparedEventis sent just before the refresh is started but after bean definitions have been loaded.”
Source: Spring Boot Reference Guide, “SpringApplication” section, docs.spring.io. No individual author is named.
Refresh is the step that turns definitions into a usable context. Boot’s documentation treats the context as refreshed once that step completes. This article does not walk through the Spring Framework’s internal refresh steps, such as bean factory post-processors, bean post-processors, singleton creation, or lifecycle callback order. Those details belong to the Spring Framework version you run. Consult the Spring Framework reference that matches your release before relying on a specific internal order.
Rank #3
6. Started, live, runners, and ready
After refresh, Boot publishes ApplicationStartedEvent, then the application and command-line runners execute. Liveness is established after refresh. Once all runners have completed, Boot publishes ApplicationReadyEvent, and readiness moves to accepting traffic. The sequence is covered in the next section, because the ordering is where most startup questions arise.
Which context type gets created
Boot selects the context from the application’s web type. The table below describes the three modes the official documentation distinguishes. It does not claim any one mode is better than the others; the right mode follows from the application’s dependencies and what it needs to serve.
| Application mode | How it is selected | What to know |
|---|---|---|
| Servlet web | Chosen when the application is a servlet-based web application. | The default factory picks a context appropriate to this mode. Check your release’s documentation for the exact class in use. |
| Reactive web | Chosen when the application is a reactive web application. | Also selected by the default factory. Startup still follows the same lifecycle events. |
| Non-web | Chosen when the application is not a web application. | Same lifecycle events apply, but no web server context is involved. |
The web type can be set explicitly with the spring.main.web-application-type property, which overrides the detection Boot would otherwise do. Setting it is useful when a dependency on the classpath would otherwise cause the wrong mode to be chosen.
Default selection versus a custom ApplicationContextFactory
The default factory covers the normal case. A custom factory is a strategy you set on SpringApplication when the context must be created differently, for example to use a specialised context class for a specific deployment. This is a deliberate extension point, and it changes how the context is created. It does not change the lifecycle events around it. If you do not have a specific reason to replace the factory, the default is the safer choice.
Rank #4
Where auto-configuration enters
Auto-configuration is part of source and bean-definition loading. It is not a separate container and not a hidden mechanism that runs beside your application. Auto-configuration classes are ordinary configuration loaded into the same context as your own classes. Boot’s auto-configuration reference describes three behaviours that matter during startup:
- It is opt-in.
@SpringBootApplicationenables it for the application. - It is classpath-aware and conditional. A configuration applies when the relevant jar dependencies are present and its conditions match.
- It backs away. When your own configuration supplies a replacement bean, the auto-configured one is not applied. Auto-configuration is designed to be non-invasive.
Seeing what was applied and what was skipped
When a bean appears unexpectedly, or one you expected is missing, run the application with --debug (for example, java -jar demo.jar --debug). The output includes the condition evaluation report, which lists auto-configurations that matched and those that did not, with the reason for each.
To suppress an auto-configuration you do not want, exclude it on the annotation:
Recommended Free Tools
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DemoApplication { }
Exclusions remove that configuration from the set Boot loads. Your own beans for the same concern still take effect, because auto-configuration is designed to back off in that case.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Refresh, liveness, and readiness are different milestones
A refreshed context is not the same as an application that is ready to serve requests. The following table separates the milestones, what each one signals, and what it does not yet imply.
| Milestone | Signal | What it establishes | What it does not yet imply |
|---|---|---|---|
| Definitions loaded | ApplicationPreparedEvent (sent just before refresh) |
Bean definitions are read and ready to be processed. | No beans are live yet; refresh has not started. |
| Context refreshed | Completion of refresh | The context is considered refreshed, and its beans are assembled. | Runners have not run, and the app may not yet accept traffic. |
| Started | ApplicationStartedEvent (after refresh, before runners) |
The context has started, and runners are about to execute. | Runner work is not finished. |
| Live | Liveness is set after refresh | The application is considered live. | Liveness does not mean it is accepting requests. |
| Ready | ApplicationReadyEvent (after runners), with readiness accepting traffic |
The application has finished its startup work and accepts traffic. | Nothing further; this is the end of startup. |
The practical consequence is that code you place in an ApplicationRunner or CommandLineRunner runs before readiness flips, so it can finish setup that the application needs before it takes traffic. Code that listens for ApplicationReadyEvent runs at the point where the application is ready to serve.
Version and source caveats
The current Spring Boot reference pages are unversioned, so the lifecycle described above is the documented public model. At the time of checking, the Spring Boot project page at spring.io/projects/spring-boot showed 4.1.1 as the current release. A SpringApplication API page for 4.2.0-M2 was also available; that is a milestone build, not a general release. The ApplicationContextFactory page cited above is for Boot 3.0.0. It confirms that the factory is a strategy interface, but it does not confirm every implementation detail in Boot 4.x.
When you make claims about method-level internals, such as which class calls which method during run, cite the exact release tag you are reading and check the source at that tag. Do not carry an internal order from one release over to another.
Further reading
The Ullenboom book Spring Boot 3 and Spring Framework 6 (SAP PRESS, 2024) covers Spring-managed bean containers and Spring Boot in depth. It targets Boot 3 and Framework 6, not the Boot 4 line discussed here. Its scope and publication details are on the SAP PRESS catalog page.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




