In Spring Boot, Application Events and Listeners allow your application components to communicate in a loosely coupled, event-driven way. Itβs a powerful technique for triggering actions like logging, monitoring, auditing, or asynchronous workflows when something meaningful happens in the app.
This post covers:
- What are Application Events?
- Built-in Spring Boot Events
- How to publish custom events
- How to register event listeners (synchronous & async)
- Real-world examples
Letβs explore how you can use Spring Boot Application Events to build reactive and maintainable applications.

π§ What Are Application Events?
Spring provides an event publishing mechanism where one component can publish an event, and other components can listen for and respond to it.
Think of it like this:
βHey, something just happened β does anyone care?β
π Step 1: Use Built-in Spring Boot Events
Spring Boot provides several lifecycle events, including:
Event Class | Description |
---|---|
ApplicationStartedEvent | App has started but not ready |
ApplicationReadyEvent | App is fully ready to serve requests |
ContextRefreshedEvent | ApplicationContext refreshed |
ContextClosedEvent | App context closed |
ApplicationFailedEvent | App startup failed |
Example Listener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.kscodes.springboot.listener; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @Component public class AppReadyListener implements ApplicationListener<ApplicationReadyEvent> { @Override public void onApplicationEvent(ApplicationReadyEvent event) { System.out.println("β
Application is fully ready!"); } } |
π§ͺ Step 2: Create a Custom Application Event
You can define your own event by extending ApplicationEvent
or simply creating a POJO (recommended since Spring 4.2).
β POJO-Based Custom Event
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.kscodes.springboot.event; public class UserCreatedEvent { private final String email; public UserCreatedEvent(String email) { this.email = email; } public String getEmail() { return email; } } |
π£ Step 3: Publish the Event
Inject ApplicationEventPublisher
in any Spring bean to publish your custom event.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.kscodes.springboot.service; import com.kscodes.springboot.event.UserCreatedEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private ApplicationEventPublisher publisher; public void registerUser(String email) { // logic to save user System.out.println("π€ User registered: " + email); publisher.publishEvent(new UserCreatedEvent(email)); } } |
π§ Step 4: Create an Event Listener
π§ Using @EventListener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.kscodes.springboot.listener; import com.kscodes.springboot.event.UserCreatedEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class UserCreatedEventListener { @EventListener public void handleUserCreated(UserCreatedEvent event) { System.out.println("π§ Sending welcome email to: " + event.getEmail()); } } |
β‘ Optional: Make Listener Asynchronous
You can run listeners on a separate thread using @Async
.
β Enable async support:
1 2 3 4 5 6 |
@SpringBootApplication @EnableAsync public class MyApp {} |
β¨ Then mark the listener async:
1 2 3 4 5 6 7 8 |
@Async @EventListener public void handleUserCreatedAsync(UserCreatedEvent event) { // time-consuming logic } |
π Real-World Use Cases
- Audit Logging: Track changes and activities across services.
- Email Notifications: Send emails without blocking user requests.
- Monitoring: Notify dashboards or external systems.
- Workflow Triggers: Kick off next steps after a process is complete.
π Bonus: Conditional Listeners
Use @EventListener(condition = "...")
to listen selectively.
1 2 3 4 5 6 7 |
@EventListener(condition = "#event.email.endsWith('@admin.com')") public void handleAdminUser(UserCreatedEvent event) { System.out.println("β οΈ Admin user detected: " + event.getEmail()); } |
π§Ή Cleaning Up with ContextClosedEvent
Listen for shutdown signals (graceful exit, cleanup, notifications).
1 2 3 4 5 6 7 8 9 10 |
@Component public class ShutdownListener implements ApplicationListener<ContextClosedEvent> { @Override public void onApplicationEvent(ContextClosedEvent event) { System.out.println("π Application is shutting down."); } } |
π§΅ Summary
Spring Boot Application Events enable you to write decoupled, maintainable, and reactive code by letting components listen for lifecycle or custom business events.
β In this guide, you learned:
- How to use built-in and custom events
- How to create and listen to events
- How to use
@EventListener
and@Async
- When to use conditional listeners
Start small β then evolve your monolith or microservice into an event-driven architecture!