Spring Boot’s Application Events

Truong Bui
6 min readJun 5, 2023

--

During the startup of a Spring Boot application, multiple stages come into play. These stages not only facilitate the application’s initialization but also provide a rich set of events that empower developers to finely tune behaviors, tailor configurations, and execute targeted actions at different phases of the startup process. By leveraging these events, developers can efficiently customize the application’s behavior, optimize performance, or seamlessly align the application with specific business requirements.

Today, we explore practical examples that demonstrate the practical applications of these events. Through these exercises, we aim to gain deeper insights into the usages and functionalities of each event, enabling us to harness their potential more effectively.

The Order of Event Raising

Let’s get started! 💪

ApplicationStartingEvent

ApplicationStartingEvent is triggered at the very beginning of the application’s startup process, just before the application context is fully initialized. At this stage, the application has just started, and various initialization tasks, such as loading configuration files and setting up the environment are not available yet.

By listening to the ApplicationStartingEvent, we can perform pre-initialization tasks, such as updating system properties, reading external configurations, initializing logging frameworks, etc.

To handle the ApplicationStartingEvent, we can create a custom event listener by implementing ApplicationListener interface with the ApplicationStartingEvent as the generic type. This listener can be registered manually in the main application class.

public class ApplicationStartingListener 
implements ApplicationListener<ApplicationStartingEvent> {
@Override
public void onApplicationEvent(ApplicationStartingEvent event) {
System.out.println("Handling ApplicationStartingEvent here!");
}
}
@SpringBootApplication
public class EventsApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(EventsApplication.class);
app.addListeners(new ApplicationStartingListener());
app.run(args);
}
}

When the application runs, the onApplicationEvent() method of the ApplicationStartingListener will be invoked, allowing us to execute any necessary tasks before the application context is fully established.

ApplicationEnvironmentPreparedEvent

ApplicationEnvironmentPreparedEvent is triggered when the application’s environment is prepared, the application context is not initialized yet at this stage.

By listening to this event, we can access the environment’s properties, profiles, and configuration sources. Then we can do some tasks such as modifying property values, adding or removing configuration sources, activating specific profiles, or applying custom logic based on the environment’s state.

To handle the ApplicationEnvironmentPreparedEvent event, we can create a custom event listener by implementing ApplicationListener interface with the ApplicationEnvironmentPreparedEvent as the generic type. This listener can be registered manually in the main application class.

public class ApplicationEnvironmentPreparedListener
implements
ApplicationListener<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
System.out.println("Handling ApplicationEnvironmentPreparedEvent here!");
}
}
@SpringBootApplication
public class EventsApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(EventsApplication.class);
app.addListeners(new ApplicationEnvironmentPreparedListener());
app.run(args);
}
}

When we run the Spring Boot application, the onApplicationEvent() method of the ApplicationEnvironmentPreparedListener will be invoked, allowing us to access and modify the application's environment as needed.

ApplicationContextInitializedEvent

ApplicationContextInitializedEvent during the preparation of the application context but before the bean definitions are loaded into the Spring container.

This event provides an opportunity to execute tasks prior to the initialization of beans, such as registering property sources and activating beans based on the environment of the context, and more.

To handle the ApplicationContextInitializedEvent event, we can create an additional initializer for the application by implementing ApplicationContextInitializer interface with the ConfigurableApplicationContext as the generic type. This initializer can be added manually in the main application class.

@Configuration
public class ApplicationContextNewInitializer
implements
ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("Handling ApplicationContextInitializedEvent here!");
}
}
@SpringBootApplication
public class EventsApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(EventsApplication.class)
.initializers(new ApplicationContextNewInitializer()).run(args);
}
}

When we run the Spring Boot application, the ApplicationContextNewInitializer will be invoked, allowing us to execute tasks as needed before any bean definitions are loaded.

ApplicationPreparedEvent

ApplicationPreparedEvent is triggered after the application context is prepared but before the bean definitions are loaded and the application is fully initialized.

By listening to the ApplicationPreparedEvent, we can access and manipulate the application context before any actual bean instantiation or dependency injection takes place. We can perform some things like modifying bean definitions, registering additional components, configuring aspects, and more.

To handle the ApplicationPreparedEvent, we can create a custom event listener by implementing the ApplicationListener interface with the ApplicationPreparedEvent as the generic type. This listener can be registered manually in the main application class.

public class ApplicationPreparedListener implements ApplicationListener<ApplicationPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationPreparedEvent event) {
System.out.println("Handling ApplicationPreparedEvent here!");
}
}
@SpringBootApplication
public class EventsApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(EventsApplication.class);
app.addListeners(new ApplicationPreparedListener());
app.run(args);
}
}

When we run the Spring Boot application, the onApplicationEvent() method of the ApplicationPreparedListener will be invoked, allowing us to access and modify the application context as needed before the initialization phase begins.

ContextRefreshedEvent

ContextRefreshedEvent is triggered when the application context initialization process is finished. At this stage, all beans have been defined in context, and the application is ready to handle requests and operations.

We can utilize the ContextRefreshedEvent to perform additional setup or initialization tasks that need to occur after the application context is fully initialized. For example, we can start background tasks, schedule jobs, establish connections to external systems, or perform any other post-initialization logic.

To handle the ContextRefreshedEvent, we can create a custom event listener by implementing the ApplicationListener interface with the ContextRefreshedEvent as the generic type. This listener can be registered manually in the main application class.

public class ContextRefreshedListener
implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("Handling ContextRefreshedEvent here!");
}
}
@SpringBootApplication
public class EventsApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(EventsApplication.class);
app.addListeners(new ContextRefreshedListener());
app.run(args);
}
}

When we run the Spring Boot application, the onApplicationEvent() method of the ContextRefreshedListener will be invoked, allowing us to perform actions or execute logic after the application context is fully initialized.

ApplicationStartedEvent

ApplicationStartedEvent is triggered when the application has started and the main method has been executed. It occurs after the application context has been created and prepared, but before the actual execution of the application's run() method.

This event provides an opportunity to perform additional tasks or execute custom logic at the start of the application, including initializing additional components, setting up logging, configuring dynamic properties, and more.

To handle the ApplicationStartedEvent, we can create a custom event listener by implementing the ApplicationListener interface with the ApplicationStartedEvent as the generic type. This listener can be registered manually in the main application class.

public class ApplicationStartedListener 
implements ApplicationListener<ApplicationStartedEvent> {
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
System.out.println("Handling ApplicationStartedEvent here!");
}
}
@SpringBootApplication
public class EventsApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(EventsApplication.class);
app.addListeners(new ApplicationStartedListener());
app.run(args);
}
}

When executing the Spring Boot application, the onApplicationEvent() method of the ApplicationStartedListener is invoked, enabling us to perform any necessary additional setups or initialization tasks at the beginning of the application.

AvailabilityChangeEvent

AvailabilityChangeEvent is triggered when there is a change in the Liveness and Readiness status of the application. For example, it can be triggered when the application transitions from LivenessState.CORRECT to indicate that the application is live and from ReadinessState.ACCEPTING_TRAFFIC to indicate that the application is ready to handle incoming requests.

To handle the AvailabilityChangeEvent, we can create a custom event listener by implementing the ApplicationListener interface with the AvailabilityChangeEvent as the generic type. This listener can be registered manually in the main application class.

public class AvailabilityChangeListener 
implements ApplicationListener<AvailabilityChangeEvent> {
@Override
public void onApplicationEvent(AvailabilityChangeEvent event) {
System.out.println("Handling AvailabilityChangeEvent here!");
}
}
@SpringBootApplication
public class EventsApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(EventsApplication.class);
app.addListeners(new AvailabilityChangeListener());
app.run(args);
}
}

When executing the Spring Boot application, we can use AvailabilityChangeEvent to update the state. Any application component can send such events to update the state of the application.

ApplicationReadyEvent

ApplicationReadyEvent is triggered when the application is fully initialized and ready to serve requests. It provides a signal that the application is up and running.

Basically, this event is the last event Spring Framework sends before the application starts to receive requests, so it’s commonly used for tasks such as starting background processes, scheduling jobs, establishing connections to external systems, etc.

To handle the ApplicationReadyEvent, we can create a custom event listener by implementing the ApplicationListener interface with the ApplicationReadyEvent as the generic type. This listener can be registered manually in the main application class.

public class ApplicationReadyListener 
implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
System.out.println("Handling ApplicationReadyEvent here!");
}
}
@SpringBootApplication
public class EventsApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(EventsApplication.class);
app.addListeners(new ApplicationReadyListener());
app.run(args);
}
}

When the application is fully initialized and ready, the onApplicationEvent() method of the ApplicationReadyListener will be invoked, enabling the execution of custom logic as required.

We have just briefly walked through Spring Boot’s Application Events concepts. This level of control enables us to optimize our applications, ensuring they run smoothly and efficiently.

I would love to hear your thoughts!

Thank you for reading, and goodbye!

--

--