๐ก Events Layer โ Springโs Internal Communication System Cheatsheet¶
Essence: The Events Layer is how Spring broadcasts important moments in the containerโs life โ from startup to shutdown โ and how your application can listen and react to them. It turns Spring into an event-driven ecosystem rather than a silent dependency injector.
๐งญ 1. Concept Overview¶
Springโs event system is built on the Observer Pattern: one part of the app publishes an event, and many others can listen to it asynchronously (or synchronously) โ without knowing about each other.
This enables loose coupling between parts of the application โ components donโt talk directly, they communicate through events.
โ๏ธ 2. The Core Interfaces¶
| Interface | Role | Typical Implementation |
|---|---|---|
ApplicationEvent |
Base type for events | Custom or built-in |
ApplicationEventPublisher |
Used to publish events | ApplicationContext implements it |
ApplicationListener<E> |
Interface for event listeners | Your listener classes |
ApplicationEventMulticaster |
Internal dispatcher | Sends events to listeners |
Typical Interaction¶
@Component
public class OrderPublisher {
@Autowired ApplicationEventPublisher publisher;
public void createOrder(Order order) {
// business logic ...
publisher.publishEvent(new OrderCreatedEvent(this, order));
}
}
@Component
public class OrderListener implements ApplicationListener<OrderCreatedEvent> {
public void onApplicationEvent(OrderCreatedEvent event) {
System.out.println("Order received โ " + event.getOrder().getId());
}
}
๐งฉ 3. Built-in Spring Events¶
Spring emits many lifecycle events as the container starts and stops:
| Event | When Itโs Published |
|---|---|
ContextRefreshedEvent |
After all beans are created & initialized |
ContextStartedEvent |
When context is explicitly started |
ContextStoppedEvent |
When context is stopped (not closed) |
ContextClosedEvent |
When context is shutting down |
ApplicationReadyEvent |
When Boot app is fully ready |
ApplicationFailedEvent |
On startup error |
WebServerInitializedEvent |
When embedded server starts (Spring Boot) |
Common Boot Example¶
@Component
public class StartupLogger {
@EventListener(ApplicationReadyEvent.class)
public void appReady() {
System.out.println("โ
Application is up and running!");
}
}
๐ง 4. Writing Custom Events¶
Create your own ApplicationEvent subclass:
public class UserRegisteredEvent extends ApplicationEvent {
private final User user;
public UserRegisteredEvent(Object source, User user) {
super(source);
this.user = user;
}
public User getUser() { return user; }
}
Publish it:
Listen for it:
@Component
public class WelcomeEmailListener {
@EventListener
public void onUserRegistered(UserRegisteredEvent e) {
System.out.println("Sending welcome email to " + e.getUser().getEmail());
}
}
โ๏ธ 5. Simplified Internal Flow¶
Your code โ publisher.publishEvent(event)
โ
ApplicationEventMulticaster finds all listeners
โ
Each listener receives onApplicationEvent(event)
Spring Boot replaces the default multicaster with a SimpleApplicationEventMulticaster, which can run listeners asynchronously if configured.
๐ 6. Asynchronous Event Handling¶
You can make listeners run in background threads:
@EnableAsync
@Component
public class AsyncListener {
@Async
@EventListener
public void handleEvent(UserRegisteredEvent e) {
System.out.println("Handling event asynchronously for " + e.getUser().getEmail());
}
}
You can also register a custom TaskExecutor for more control.
๐งฉ 7. Event Ordering and Filtering¶
Listener Order¶
@EventListener
@Order(1)
public void beforeEvent(...) { ... }
@EventListener
@Order(2)
public void afterEvent(...) { ... }
Conditional Listening¶
@EventListener(condition = "#event.user.premium == true")
public void handlePremium(UserRegisteredEvent event) {
System.out.println("Premium user signup detected!");
}
This uses Spring Expression Language (SpEL) to filter events.
๐งฎ 8. Programmatic Registration¶
Sometimes listeners are registered manually, especially in frameworks.
ctx.addApplicationListener((ApplicationEvent event) -> {
if (event instanceof ContextRefreshedEvent)
System.out.println("Context refreshed!");
});
๐งฑ 9. Event Publishing in Boot Lifecycle¶
Spring Boot itself uses the event system for application phases:
ApplicationStartingEvent
โ
ApplicationEnvironmentPreparedEvent
โ
ApplicationPreparedEvent
โ
ApplicationStartedEvent
โ
ApplicationReadyEvent
โ
ApplicationFailedEvent (if any errors)
You can listen to these via ApplicationListener or @EventListener โ
useful for startup diagnostics or pre-initialization hooks.
๐งฉ 10. Advanced: Custom Multicaster¶
You can override the multicaster bean to change event dispatching behavior.
@Bean(name = "applicationEventMulticaster")
public ApplicationEventMulticaster asyncMulticaster() {
SimpleApplicationEventMulticaster m = new SimpleApplicationEventMulticaster();
m.setTaskExecutor(new SimpleAsyncTaskExecutor());
return m;
}
This makes all events asynchronous by default.
โก 11. Common Pitfalls¶
| Problem | Cause | Fix |
|---|---|---|
| Listener not firing | Bean not registered in context | Annotate with @Component |
| Event missed | Published before listener initialized | Use SmartApplicationListener or reorder |
| Async listener not async | Missing @EnableAsync |
Enable async in config |
| Wrong event type | Mismatched generic in ApplicationListener |
Match exact class or use wildcard |
| Context events duplicated | Multiple contexts in Boot | Use ApplicationContextAware to filter |
๐งฉ 12. Visual Summary¶
+------------------------+
| ApplicationContext |
| implements Publisher |
+----------+-------------+
|
publishEvent(event)
โ
+--------------------------+
| ApplicationEventMulticaster |
| - Finds all listeners |
| - Calls them sequentially |
+--------------------------+
โ
@EventListener / ApplicationListener
๐งญ 13. Quick Reference Summary¶
| Concept | Role | Example |
|---|---|---|
| Event | Object describing an occurrence | UserRegisteredEvent |
| Publisher | Sends events | ApplicationEventPublisher |
| Listener | Reacts to events | @EventListener, ApplicationListener |
| Multicaster | Dispatches events to listeners | SimpleApplicationEventMulticaster |
| Built-in Events | Context lifecycle | ContextRefreshedEvent, ContextClosedEvent |
| Async Support | Parallel handling | @Async, @EnableAsync |
| Filtering | Conditional execution | SpEL in @EventListener |
| Boot Phases | Startup notifications | ApplicationReadyEvent, etc. |
๐ Related¶
๐ช Core Takeaway¶
The Events Layer is the voice of the container. When the Spring world changes โ beans created, contexts started, servers ready โ it speaks through events. Your code can listen in, respond, and join the rhythm of the framework itself.