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) {}@Servicepublic class OrderNotificationListener {private final EmailClient emailClient;public OrderNotificationListener(EmailClient emailClient) {this.emailClient = emailClient;}@Async("notificationTaskExecutor")@EventListenerpublic 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.