2.11 Spring Events
Use Spring Events to decouple domains and react to "order completed", "user registered", etc., with listeners (e.g. notification, settlement, inventory update).
Reference: Spring Boot 3.2.x
1. Event Class
public class OrderCompletedEvent {
private final Long orderId;
private final String userId;
public OrderCompletedEvent(Long orderId, String userId) {
this.orderId = orderId;
this.userId = userId;
}
// getters
}
- You can extend ApplicationEvent, or since Spring 4.2+ a plain POJO works fine.
2. Publishing
@Service
@RequiredArgsConstructor
public class OrderService {
private final ApplicationEventPublisher publisher;
@Transactional
public void completeOrder(Long orderId) {
// business logic
Order order = orderRepository.findById(orderId).orElseThrow();
order.complete();
orderRepository.save(order);
publisher.publishEvent(new OrderCompletedEvent(orderId, order.getUserId()));
}
}
- Inject ApplicationEventPublisher and call publishEvent(...) to publish.
- By default, listeners run synchronously —
completeOrderreturns only after all listeners finish.
3. Listener
@Component
@Slf4j
public class OrderEventListener {
@EventListener
public void onOrderCompleted(OrderCompletedEvent event) {
log.info("Order completed: orderId={}", event.getOrderId());
notificationService.sendOrderComplete(event.getUserId(), event.getOrderId());
}
}
- @EventListener: Called when an event matching the method parameter type is published.
4. Async Listener
To run a listener on a separate thread, combine with @Async.
@Async
@EventListener
public void onOrderCompletedAsync(OrderCompletedEvent event) {
// async processing
}
- Requires @EnableAsync. Transaction boundaries differ from the publisher's, so a new transaction may be needed for DB access inside the listener.
5. Conditional (SpEL)
@EventListener(condition = "#event.orderId != null")
public void onOrderCompletedConditional(OrderCompletedEvent event) {
// only runs when orderId is not null
}
tip
Use @TransactionalEventListener for "run only after commit" to keep data consistency — the listener won't run if the transaction is rolled back.