skip to content

SpringApplication & Lifecycle

What SpringApplication does around your context: startup and the builder, runners, application events, banner and lazy init and graceful shutdown, and failure analysis. Interviewers ask so they can find out how much of the startup sequence you can name.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

24

What is ApplicationReadyEvent in Spring Boot and when should you run code on it?

level: juniorimportance: must knowfreq 62%

answer

  1. last successful-startup event
  2. after refresh AND after runners
  3. web server already accepting traffic
  4. @EventListener works (context exists)
  5. not published on failure

basics

~20 s

ApplicationReadyEvent fires when the application has fully started — the context is refreshed and all runners have finished — so it is safe to say the app is ready to serve requests. Use it for startup work that needs a fully live app.

solid answer

~40 s

ApplicationReadyEvent is published by SpringApplication as the last step of startup, after the ApplicationContext is refreshed and after every CommandLineRunner and ApplicationRunner has completed. At that point all beans exist and the web server is accepting connections, so it is the safe place for 'app is live' side effects: warming caches, kicking off background schedulers, emitting a 'started' metric, or notifying an external system. You listen with a normal @EventListener or an ApplicationListener bean because the context already exists. Contrast it with ContextRefreshedEvent (fires earlier, before runners and before the servlet container is guaranteed ready) and ApplicationStartedEvent (after refresh but before runners). If startup fails, ApplicationReadyEvent is never published; ApplicationFailedEvent is published instead.

code

java · 14 lines
java
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
class StartupTasks {

    @EventListener(ApplicationReadyEvent.class)
    void warmCachesAndAnnounce(ApplicationReadyEvent event) {
        long ms = event.getTimeTaken().toMillis(); // startup duration
        // context fully refreshed, runners done, server accepting traffic
        // -> safe to warm caches / start schedulers / emit 'started' metric
    }
}

go deeper

for a junior

Know it means 'app fully started, safe to do startup side effects' and that a plain @EventListener bean works.

for a middle

Distinguish Ready vs Started vs ContextRefreshed and know it's skipped on failure.

for a senior

Discuss ordering relative to runners, AvailabilityChangeEvent/readiness probes, and the risk of blocking work here.

for a principal

Reason about readiness-probe gating, thread of execution, and using it as a system 'live' boundary vs. availability state transitions.

## What it is `ApplicationReadyEvent` is a Spring Boot application-lifecycle event (class `org.springframework.boot.context.event.ApplicationReadyEvent`) published by `SpringApplication.run(...)` at the very end of a successful startup. 'Published' means Spring's event mechanism broadcasts an object to interested listeners. ## Exactly when it fires Startup proceeds through an ordered sequence. `ApplicationReadyEvent` is published **after**: 1. The `ApplicationContext` (the Spring container holding all beans) has been *refreshed* — every singleton bean is created and initialized. 2. `ApplicationStartedEvent` has been published. 3. **All** `CommandLineRunner` and `ApplicationRunner` beans have run to completion. So when it fires, the application is fully wired and, for a web app, the embedded server (Tomcat/Netty) is up and accepting traffic. This makes it the canonical 'the app is now live' hook. ## How to listen Because the context already exists, you use ordinary listener mechanisms: ```java @Component class ReadyHandler { @EventListener(ApplicationReadyEvent.class) void onReady(ApplicationReadyEvent e) { /* ... */ } } ``` or implement `ApplicationListener<ApplicationReadyEvent>`. Both work here — unlike the *early* events (ApplicationStartingEvent, ApplicationEnvironmentPreparedEvent) which fire before any bean exists. ## When to use it - Warm caches or connection pools once everything is available. - Start long-running background tasks/schedulers that should not run mid-startup. - Publish a 'started' health/metric signal or notify a discovery service. - Trigger a one-time job that needs the full context and a listening web server. ## Gotchas / edge cases - **Do not** put slow blocking work here if you also gate readiness probes on it — you delay traffic acceptance. Boot separately publishes an `AvailabilityChangeEvent(ReadinessState.ACCEPTING_TRAFFIC)` right after readiness. - If startup throws, this event is **never** published; you get `ApplicationFailedEvent` instead. Don't rely on ReadyEvent for cleanup that must always run. - Listeners run on the main startup thread, so an exception thrown in a ReadyEvent listener can fail the boot process. - It is distinct from `ContextRefreshedEvent`, which fires earlier (on every refresh, and before runners); prefer ReadyEvent when you truly mean 'the whole application finished starting'. ## Related events `ApplicationStartedEvent` (post-refresh, pre-runners) vs `ApplicationReadyEvent` (post-runners). If you need to act before user code runners, use Started; to act after everything, use Ready.

  • What is the difference between ApplicationReadyEvent and ApplicationStartedEvent?
    ApplicationStartedEvent fires right after the context is refreshed but BEFORE any CommandLineRunner/ApplicationRunner runs. ApplicationReadyEvent fires AFTER all those runners complete — it is the true 'fully started' signal.
  • Why might you prefer ApplicationReadyEvent over ContextRefreshedEvent?
    ContextRefreshedEvent fires on every context refresh and before runners, and doesn't guarantee the app finished its full boot sequence. ApplicationReadyEvent fires once, after runners, when the app is genuinely live.

saying these in an interview costs you the question

  • Saying ApplicationReadyEvent fires before the runners
  • Claiming it's published even when startup fails
  • Confusing it with ContextRefreshedEvent as identical
  • Thinking you must register it via spring.factories (it's a normal bean listener)

context

open as a page

What are CommandLineRunner and ApplicationRunner in Spring Boot, and when do they run?

level: juniorimportance: must knowfreq 65%

basics

~10 s

They are interfaces with a single run() method. Spring Boot calls every such bean once at startup, after the application context is fully built, so you can run one-off initialization code.

open as a page

What does SpringApplication.run(...) do when a Spring Boot application starts?

level: juniorimportance: must knowfreq 78%

basics

~10 s

SpringApplication.run() bootstraps the app: it creates and configures the Spring ApplicationContext, runs auto-configuration, starts any embedded web server, and returns the running context. It's the one line called from main().

open as a page

What is the difference between CommandLineRunner and ApplicationRunner?

level: middleimportance: must knowfreq 60%

basics

~10 s

Both run once at startup. CommandLineRunner.run receives the raw String[] arguments. ApplicationRunner.run receives an ApplicationArguments object that has already parsed those strings into --option flags and plain (non-option) arguments.

open as a page

How does Spring Boot decide whether an app is SERVLET, REACTIVE, or NONE, and how do you override it?

level: middleimportance: must knowfreq 62%

basics

~20 s

Boot inspects the classpath. If Spring MVC (servlet) classes are present it picks SERVLET; if only WebFlux is present it picks REACTIVE; if no web classes are present it picks NONE. Override with setWebApplicationType() or spring.main.web-application-type.

open as a page

Why can't a @Component @EventListener catch ApplicationStartingEvent or ApplicationEnvironmentPreparedEvent, and how do you listen to those early events?

level: seniorimportance: must knowfreq 40%

basics

~10 s

Those events fire before the ApplicationContext and its beans exist, so a bean-based @EventListener isn't registered yet. You must register an ApplicationListener before the context is built — via SpringApplication.addListeners(), SpringApplicationBuilder.listeners(), or META-INF/spring.factories.

open as a page

How do you write and register a custom FailureAnalyzer for your own startup exception?

level: seniorimportance: must knowfreq 30%

basics

~10 s

Extend AbstractFailureAnalyzer<YourException>, override analyze() to return a FailureAnalysis with a description and action, then register the class name in META-INF/spring.factories under the org.springframework.boot.diagnostics.FailureAnalyzer key.

open as a page

What is a Spring Boot FailureAnalyzer, and what produces the "APPLICATION FAILED TO START" message you see when startup fails?

level: juniorimportance: should knowfreq 35%

basics

~20 s

A FailureAnalyzer turns a startup exception into a friendly error with a Description and an Action to fix it. Spring Boot prints these as the "APPLICATION FAILED TO START" banner instead of a raw stack trace.

open as a page

Walk through the ordered sequence of Spring Boot application lifecycle events during startup.

level: middleimportance: should knowfreq 45%

basics

~10 s

Roughly: ApplicationStartingEvent, then ApplicationEnvironmentPreparedEvent, then ApplicationContextInitializedEvent, then ApplicationPreparedEvent (context refreshes here), then ApplicationStartedEvent, then ApplicationReadyEvent. On error, ApplicationFailedEvent fires instead.

open as a page

What does a FailureAnalysis contain, and how do built-in analyzers like the port-in-use and missing-bean analyzers use it?

level: middleimportance: should knowfreq 40%

basics

~20 s

FailureAnalysis holds three things: a description (what went wrong), an action (how to fix it), and the original cause. The port-in-use analyzer describes the busy port; the missing-bean analyzer names the required bean and suggests defining it.

open as a page

What are 'primary sources' passed to SpringApplication, and how do they differ from component scanning?

level: middleimportance: should knowfreq 40%

basics

~20 s

Primary sources are the classes (or bean-definition sources) you hand to SpringApplication to seed the context — usually your one @SpringBootApplication class. Component scanning then discovers the rest of your beans from that class's package downward.

open as a page

What does spring.main.lazy-initialization=true do, and what are its trade-offs?

level: middleimportance: should knowfreq 45%

basics

~10 s

It makes every bean lazy: beans are created the first time they're needed instead of at startup. Startup gets faster, but startup-time errors and slow bean creation are deferred to first use.

open as a page

What is SpringApplicationRunListener, how is it registered, and how does it relate to the lifecycle events?

level: seniorimportance: should knowfreq 28%

basics

~10 s

SpringApplicationRunListener is the low-level hook Spring Boot calls during the run sequence (starting, environmentPrepared, contextPrepared, contextLoaded, started, ready, failed). Boot's built-in one publishes the lifecycle events. You register custom ones via META-INF/spring.factories.

open as a page

How does ApplicationArguments parse option versus non-option arguments, and what do its accessor methods return?

level: seniorimportance: should knowfreq 45%

basics

~10 s

Tokens shaped like --name or --name=value become 'option' arguments; everything else is a 'non-option' argument. getOptionValues(name) returns a List of that option's values, getNonOptionArgs() returns the plain tokens, and getSourceArgs() returns the raw array.

open as a page

How do you control the execution order of multiple runners, and what is the ordering scope?

level: seniorimportance: should knowfreq 40%

basics

~10 s

Annotate each runner with @Order(n) or implement Ordered. Lower numbers run first. Spring puts all ApplicationRunner and CommandLineRunner beans into one combined list and sorts by that value, so ordering spans both interface types.

open as a page

What is SpringApplicationBuilder and when would you use its parent/child context feature?

level: seniorimportance: should knowfreq 34%

basics

~10 s

SpringApplicationBuilder is a fluent API for configuring and launching a SpringApplication. Its distinctive feature is building a parent/child ApplicationContext hierarchy — a shared parent context whose beans are visible to isolated child contexts.

open as a page

How does server.shutdown=graceful work, and what role does spring.lifecycle.timeout-per-shutdown-phase play?

level: seniorimportance: should knowfreq 50%

basics

~10 s

server.shutdown=graceful makes the embedded web server stop accepting new requests but finish in-flight ones before shutting down. spring.lifecycle.timeout-per-shutdown-phase (default 30s) caps how long it waits for those requests before forcing shutdown.

open as a page

What can you customize on a SpringApplication BEFORE the context refreshes, and how do you hook in?

level: principalimportance: should knowfreq 30%

basics

~20 s

Before refresh you can set defaults on the SpringApplication instance: default properties, additional profiles, banner mode, web type, lazy initialization, and register ApplicationContextInitializers and ApplicationListeners. These run during the early bootstrap phases, before beans are instantiated.

open as a page

How do you customize or disable the Spring Boot startup banner?

level: juniorimportance: nice to knowfreq 25%

basics

~10 s

Put a banner.txt file on the classpath root and Spring Boot prints it at startup. To turn it off, set spring.main.banner-mode=off in application.properties.

open as a page

At what point in the SpringApplication lifecycle do FailureAnalyzers run, and why does that timing dictate how you get dependencies into them?

level: seniorimportance: nice to knowfreq 15%

basics

~10 s

They run after startup has already failed — when SpringApplication catches the fatal exception and reports it, before rethrowing. Because the context is dead, you can't autowire beans; you use EnvironmentAware/BeanFactoryAware injection instead.

open as a page

How does ApplicationFailedEvent work, and how would you use it (and the early listeners) to build robust startup diagnostics?

level: principalimportance: nice to knowfreq 20%

basics

~20 s

ApplicationFailedEvent is published when startup throws, carrying the exception and (if it got that far) the context. Because failures can occur before the context exists, listen with an early ApplicationListener registered outside the context so you can log/alert reliably.

open as a page

A team's custom FailureAnalyzer is never invoked — the app still prints a raw stack trace. What are the likely causes, and how do analyzer ordering and null returns factor in?

level: principalimportance: nice to knowfreq 12%

basics

~20 s

Common causes: registered in the wrong file (the AutoConfiguration.imports file instead of spring.factories), declared as a bean, wrong factory key, generic typed to a wrapper instead of the real exception, or analyze() returning null. Also, another analyzer may match first.

open as a page

Runners execute after the web server has already started. What are the readiness implications, and when should you use ApplicationReadyEvent or other alternatives instead?

level: principalimportance: nice to knowfreq 25%

basics

~20 s

The embedded web server starts during context refresh, before runners run, so requests can arrive while a runner is still working. If startup work must gate traffic, use readiness probes plus ApplicationReadyEvent (published after runners) rather than assuming a runner blocks traffic.

open as a page

What actually triggers Spring Boot's graceful shutdown, and how does the SmartLifecycle phase system enforce the drain timeout?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

Graceful shutdown runs when the ApplicationContext closes — usually because a SIGTERM fires the JVM shutdown hook. The embedded server is a SmartLifecycle bean in the shutdown phase, and timeout-per-shutdown-phase caps how long that phase waits for in-flight requests.

open as a page