What happens when you call SpringApplication.run()?
Quick Answer
SpringApplication.run() bootstraps the entire application in one call: it determines the application type (servlet web, reactive web, or none), creates and prepares the Environment (loading configuration properties and active profiles), creates the appropriate ApplicationContext, runs any registered ApplicationContextInitializers, loads and refreshes the context (triggering component scanning, auto-configuration, and bean instantiation), starts the embedded web server if applicable, and finally runs any CommandLineRunner/ApplicationRunner beans — publishing a series of ApplicationEvents (ApplicationStartingEvent, ApplicationReadyEvent, etc.) along the way that other beans can listen for.
Detailed Answer
SpringApplication.run(MyApp.class, args) is a single call that performs the entire application bootstrap sequence:
- Determine the application type — servlet-based web application, reactive web application, or a plain non-web application — inferred from what's on the classpath.
- Prepare the
Environment— load configuration fromapplication.properties/.yml, environment variables, command-line arguments, and determine active profiles, all before any bean is created. - Print the banner (the ASCII-art Spring Boot banner, if not disabled) and run any registered
ApplicationContextInitializers, which get a chance to further customize the context before it's refreshed. - Create the
ApplicationContext— the concrete type matching the detected application type (e.g.,AnnotationConfigServletWebServerApplicationContextfor a servlet web app). - Refresh the context — this is where the bulk of the real work happens: component scanning discovers
@Component-annotated classes, auto-configuration classes are evaluated and conditionally applied, all bean definitions are instantiated and wired together (following the bean lifecycle), and — for a web application — the embedded server starts as part of this same refresh. - Run runners — any beans implementing
CommandLineRunnerorApplicationRunnerare executed, in order, right after the context is fully ready — a common place to put one-off startup logic (seeding data, printing startup diagnostics).
Throughout this sequence, Spring Boot publishes a series of ApplicationEvents other beans can listen for via @EventListener: ApplicationStartingEvent, ApplicationEnvironmentPreparedEvent, ApplicationContextInitializedEvent, ApplicationPreparedEvent, ApplicationStartedEvent, and finally ApplicationReadyEvent — commonly used as the signal that the application is fully up and ready to serve traffic (e.g., to trigger a final cache warm-up or register with a service registry only once startup has genuinely completed).
@Component
class StartupLogger {
@EventListener(ApplicationReadyEvent.class)
void onReady() {
System.out.println("Application fully started and ready to serve traffic");
}
}