Free tools Windows power users keep installed
One-click scans. No signup required.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
When a Spring Boot application starts, `SpringApplication.run` turns your application sources and configuration into a refreshed Spring `ApplicationContext` in a fixed sequence. It prepares the environment, chooses a context type, runs initializers, loads sources and auto-configuration as bean definitions, and only then refreshes the context. Application and command-line runners execute after refresh, and the application starts accepting traffic last. Here, “container” means the Spring `ApplicationContext`, not a Docker container.
The order below follows the Spring Boot Reference Guide’s documented lifecycle. The exact method-level call order inside `SpringApplication` changes between releases, so treat the sequence as the stable contract and check code-level details against the release you run.
The two objects that matter: SpringApplication and ApplicationContext
SpringApplication is the coordinator. It reads configuration, decides what kind of context to build, fires lifecycle events, and hands the finished context back to your code. The ApplicationContext is the configured Spring container that holds bean definitions, bean instances, and most of the application’s runtime state. Boot builds the context on your behalf; the context does not orchestrate its own startup.
Keeping these roles apart explains most of the behavior you see. Anything Boot does before a context exists must happen inside SpringApplication. Anything that depends on bean wiring happens inside the context.
#1 Best Overall
The startup sequence at a glance
The table lists the events and steps in the order Boot performs them. The “Context state” column is the important one: it tells you what is and is not available to your code at each point.
| Order | Event or step | Context state | What happens |
|---|---|---|---|
| 1 | ApplicationStartingEvent |
No context yet | The first lifecycle event, sent to listeners registered before the run begins. |
| 2 | ApplicationEnvironmentPreparedEvent |
No context yet | The environment is complete, including command-line arguments exposed as properties. |
| 3 | Context creation | Created, not configured | An ApplicationContextFactory selects a context type for the application’s web type. |
| 4 | Initializers run | Configured, no definitions loaded | Each ApplicationContextInitializer customizes the context before any definitions arrive. |
| 5 | ApplicationContextInitializedEvent |
Initialized | Sent after initializers and before bean definitions are loaded. |
| 6 | Sources loaded | Bean definitions registered | The primary source, its configuration classes, and auto-configuration candidates are registered as definitions. |
| 7 | ApplicationPreparedEvent |
Definitions loaded, not refreshed | Sent just before refresh starts. |
| 8 | Refresh | Refreshed | The Spring Framework refresh process runs. The context is now considered refreshed. |
| 9 | ApplicationStartedEvent |
Refreshed | Sent after refresh and before runners. Boot marks the application live after refresh; the exact call site varies by release. |
| 10 | Runners execute | Refreshed | ApplicationRunner and CommandLineRunner beans are invoked. |
| 11 | ApplicationReadyEvent |
Refreshed | Sent after runners. Readiness changes to accepting traffic. |
Step by step
1. Bootstrap and environment
A Java main method commonly calls SpringApplication.run(DemoApplication.class, args). Before any context exists, Boot builds the environment: profiles, property sources from files and the OS, and the command-line arguments. Arguments such as --server.port=8081 become properties, which is why they can override values from application.properties. The ApplicationEnvironmentPreparedEvent is the earliest point at which the complete environment is visible to listeners, and it still arrives before a context is created.
2. Choosing and creating the context
Boot chooses a context based on the application’s web type. The default selection is made by ApplicationContextFactory, the strategy interface Boot uses to create the context. The Boot 3.0.0 API page describes the default implementation as choosing an appropriate context for the web application type. Current releases use the following classes by default:
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 errors| Application mode | Default context class | Typical trigger |
|---|---|---|
| Servlet web | AnnotationConfigServletWebServerApplicationContext |
A servlet web stack is on the classpath (for example Spring MVC with an embedded servlet container). |
| Reactive web | AnnotationConfigReactiveWebServerApplicationContext |
A reactive web stack is present and no servlet stack is selected. |
| Non-web | AnnotationConfigApplicationContext |
No web server is needed, such as batch jobs or command-line tools. |
The class names above reflect the defaults in recent Boot releases. Confirm them in the release you run, since the selection logic is an internal detail.
You can replace the factory when the default is not right for your application. Pass your own implementation to SpringApplication before calling run:
Rank #2
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setApplicationContextFactory(webType -> new AnnotationConfigApplicationContext());
app.run(args);
A custom factory is an advanced choice. Most applications should leave the default in place and use configuration, not a different context class, to change behavior.
3. Initializing before definitions are loaded
ApplicationContextInitializer implementations run after the context exists but before any bean definitions are loaded. This is the window for early context customization, such as registering property sources or setting context-level flags. Once initializers finish, Boot sends ApplicationContextInitializedEvent, which is still before definitions arrive.
Listeners that must see events from before the context exists cannot be ordinary beans, because no context is available to hold them yet. Register them directly on the SpringApplication or through SpringApplicationBuilder:
SpringApplication app = new SpringApplication(DemoApplication.class);
app.addListeners(new MyStartupListener());
app.run(args);
4. Loading sources and configuration
The primary source is the class you pass to SpringApplication, commonly the one annotated with @SpringBootApplication. The SpringApplication API treats these sources as the inputs from which the context’s bean definitions are built. @SpringBootApplication also opts the application into auto-configuration through @EnableAutoConfiguration, and that is where most of the framework’s default beans come from.
At this stage Boot registers definitions, not instances. Beans are not yet instantiated in the usual sense, so this is the point to think of as “what the container will build,” not “what exists.”
Rank #3
5. Prepared event and refresh
The Spring Boot Reference Guide describes the boundary in its own words:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
“An
ApplicationPreparedEventis sent just before the refresh is started but after bean definitions have been loaded.”Source: Spring Boot Reference Guide, “SpringApplication” section. No individual author is named. Spring Boot Reference Guide: SpringApplication
Refresh is the Spring Framework process that turns registered definitions into a usable context. The Boot-level sources establish this boundary but do not enumerate every Framework step inside refresh, such as bean factory post-processing, singleton creation, or lifecycle callbacks. For those details, read the Spring Framework documentation for the version your application uses. Do not assume a universal order from Boot-level material alone.
6. After refresh: started, runners, and ready
ApplicationStartedEvent follows refresh and comes before runners. Application and command-line runners run next, which is the usual place for work that needs a fully wired context, such as loading reference data. ApplicationReadyEvent is sent after the runners finish, and readiness changes to accepting traffic at that point.
Rank #4
Because the ready event comes after the runners, a runner that throws an exception prevents it from being published. Startup fails, and the application never reaches the ready state. Keep long-running work out of runners, or move it to a background task that does not block startup.
Bean definitions, refresh, liveness, and readiness are different milestones
These four terms are often used interchangeably, but they answer different questions. Confusing them leads to health probes that report the wrong state.
| Milestone | Question it answers | Where it happens |
|---|---|---|
| Bean definitions loaded | Does the container know what it is supposed to build? | Before ApplicationPreparedEvent |
| Refreshed | Has the Framework finished assembling the context? | Refresh step, before ApplicationStartedEvent |
| Live | Is the application running and not in a broken state? | After refresh; used by liveness probes |
| Ready | Can the application accept traffic now? | After runners and ApplicationReadyEvent; used by readiness probes |
A refreshed context does not guarantee readiness, because runners may still be doing work. Conversely, a live application may be temporarily not ready. With Spring Boot Actuator, the liveness and readiness states are exposed as health groups, typically at /actuator/health/liveness and /actuator/health/readiness when probe support is enabled.
Where auto-configuration enters
Auto-configuration is registered during the sources-loading step. It is not a separate container and it does not run in its own phase. Its candidates become ordinary bean definitions, and each one is applied only when its conditions match. Those conditions usually depend on classes on the classpath, existing beans, and properties.
Recommended Free Tools
Auto-configuration is also non-invasive. When your own configuration defines a bean of the same kind, the auto-configured version backs away. That is why you can replace a default by declaring your own bean.
Inspecting what was applied
Start the application with the debug flag to get the condition evaluation report, which lists which auto-configurations matched and which did not:
java -jar target/demo-0.0.1-SNAPSHOT.jar --debug
Excluding a configuration
To suppress a specific auto-configuration, exclude it on the annotation:
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
The exclusion can also be set as a property, spring.autoconfigure.exclude, which is useful when you cannot edit the annotation. In both cases, the excluded class is never registered as a definition, so there is nothing for the condition report to evaluate.
Version-dependent details
- The Spring Boot project page showed 4.1.1 as the current release when it was checked.
- The SpringApplication API page is for 4.2.0-M2, a milestone release. Its description of the lifecycle events matches the reference guide, but milestone code can change before a general release.
- The
ApplicationContextFactoryAPI page is for Boot 3.0.0. It confirms the strategy interface and the default selection behavior, but it does not establish every implementation detail for Boot 4.x. - The Reference Guide pages are unversioned. Treat their event order and the readiness boundary as stable, and verify internal method calls against the exact Boot tag before you rely on them in code.
Primary sources for this article: Spring Boot project page, Spring Boot Reference Guide: SpringApplication, SpringApplication API (4.2.0-M2), ApplicationContextFactory API (3.0.0), and Spring Boot Reference Guide: Auto-configuration.
Quick Recap
Checklist for diagnosing startup order
- If a listener must see the environment or context-creation events, register it on
SpringApplication, not as a bean. - If a property does not take effect, check whether it was set before refresh. Environment values are available early; bean-level values set after refresh may be too late for code that already read them.
- If an auto-configured bean is unexpected, run with
--debugand read the condition report before adding exclusions. - If the application is live but never ready, look for a runner that is blocking or failing.
- If behavior differs between Boot versions, compare the startup logic in the tag you run with the tag you tested.
“
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.

