Unlock Spring Boot Startup: All Events Explained with Code Samples
This article explains every Spring Boot startup event, from ApplicationStartingEvent to ApplicationFailedEvent, showing when each occurs, how to customize them, and providing clear code examples to help developers extend and debug their applications effectively.
Overview
In the Spring framework, events implement a publish‑subscribe model that enables decoupled communication for logging, notifications, transaction handling, and more. Spring provides many built‑in events (e.g., ApplicationContextInitializedEvent, ApplicationStartingEvent) and allows custom events. Understanding the events triggered during Spring Boot startup lets you know where to extend functionality.
Event Triggering Sequence
2.1 ApplicationStartingEvent
This event fires before the ApplicationContext is instantiated.
<code>public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// Get EventPublishingRunListener from configuration
SpringApplicationRunListeners listeners = getRunListeners(args);
// Trigger ApplicationStartingEvent
listeners.starting(bootstrapContext, this.mainApplicationClass);
}
}
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
public void starting(ConfigurableBootstrapContext bootstrapContext) {
this.initialMulticaster.multicastEvent(
new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
}
}
</code>2.2 ApplicationEnvironmentPreparedEvent
This event indicates that the Environment is ready and the application.yml has been parsed.
<code>public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
}
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
// Trigger event
listeners.environmentPrepared(bootstrapContext, environment);
}
}
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
this.initialMulticaster.multicastEvent(
new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.application, this.args, environment));
}
}
</code>2.3 ApplicationContextInitializedEvent
Published just before the ApplicationContext instance is created.
<code>public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
ConfigurableApplicationContext context = null;
context = createApplicationContext();
// Prepare context
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
}
private void prepareContext(...) {
context.setEnvironment(environment);
applyInitializers(context);
// Trigger ApplicationContextInitializedEvent
listeners.contextPrepared(context);
}
}
</code>2.4 ApplicationPreparedEvent
Fires before the context is refreshed, registering beans such as ApplicationArguments , Banner , and various post‑processors.
<code>public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
ConfigurableApplicationContext context = null;
context = createApplicationContext();
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
}
private void prepareContext(...) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
Set<Object> sources = getAllSources();
load(context, sources.toArray(new Object[0]));
// Trigger event
listeners.contextLoaded(context);
}
}
</code>2.5 ServletWebServerInitializedEvent
Occurs at the final stage of context refresh when a SmartLifecycle bean (e.g., WebServerStartStopLifecycle ) starts the embedded web server.
<code>public abstract class AbstractApplicationContext {
public void refresh() {
finishRefresh();
}
protected void finishRefresh() {
getLifecycleProcessor().onRefresh();
}
}
class WebServerStartStopLifecycle implements SmartLifecycle {
private final WebServer webServer;
private volatile boolean running;
@Override
public void start() {
this.webServer.start();
this.running = true;
this.applicationContext.publishEvent(
new ServletWebServerInitializedEvent(this.webServer, this.applicationContext));
}
}
</code>2.6 ContextRefreshedEvent
Published after the Spring container completes its refresh process.
<code>public abstract class AbstractApplicationContext {
public void refresh() {
finishRefresh();
}
protected void finishRefresh() {
// Spring container fully initialized
publishEvent(new ContextRefreshedEvent(this));
}
}
</code>2.7 ApplicationStartedEvent
Dispatched once the Spring container has been fully initialized.
<code>public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// ...
refreshContext(context);
// Container fully initialized, publish event
listeners.started(context, timeTakenToStartup);
}
}
</code>2.8 AvailabilityChangeEvent (first occurrence)
Emitted together with the previous events to signal readiness state changes.
<code>public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// ...
refreshContext(context);
// Trigger AvailabilityChangeEvent
listeners.started(context);
}
}
public class EventPublishingRunListener {
public void started(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}
}
</code>2.9 ApplicationReadyEvent
Indicates the application is ready to accept traffic.
<code>public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// Refresh context
refreshContext(context);
try {
// Trigger ApplicationReadyEvent
listeners.ready(context, timeTakenToReady);
} catch (Exception ex) {
// handle
}
}
}
public class EventPublishingRunListener {
public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}
}
</code>2.10 AvailabilityChangeEvent (second occurrence)
Sent immediately after the readiness state changes to indicate the app can serve requests.
<code>public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// ...
listeners.started(context);
// Event published together with previous events
}
}
</code>2.11 ApplicationFailedEvent
Triggered when an exception occurs during the publishing of earlier events.
<code>public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
// Refresh context
refreshContext(context);
try {
listeners.ready(context, timeTakenToReady);
} catch (Throwable ex) {
// Publish ApplicationFailedEvent
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
}
}
</code>Conclusion
The Spring Boot event mechanism provides a flexible and extensible way to enhance application functionality and maintainability. By leveraging these events, developers can efficiently connect components, implement custom behavior, and improve information flow within their applications.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.