0 day streak
java / intermediate
Snippet

Non-Blocking Domain Event Handling with @Async and @EventListener

Combining @EventListener with @Async allows Spring applications to publish domain events synchronously from business logic while executing slow side-effects (such as sending notifications) concurrently on a dedicated thread pool.

snippet.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public record OrderCreatedEvent(Long orderId, String customerEmail) {}
@Service
public class OrderNotificationListener {
private final EmailClient emailClient;
public OrderNotificationListener(EmailClient emailClient) {
this.emailClient = emailClient;
}
@Async("notificationTaskExecutor")
@EventListener
public CompletableFuture<Void> handleOrderCreated(OrderCreatedEvent event) {
emailClient.sendOrderConfirmation(event.customerEmail(), event.orderId());
return CompletableFuture.completedFuture(null);
}
}
spring
Breakdown
1
public record OrderCreatedEvent(Long orderId, String customerEmail) {}
Defines an immutable data carrier representing the state changes for the domain event.
2
@Async("notificationTaskExecutor")
Specifies that the listener method must run asynchronously on the named custom task executor bean.
3
@EventListener
Registers this method as an application listener matching the OrderCreatedEvent parameter payload.