Skip to main content
Advertisement

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 synchronouslycompleteOrder returns 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.

Advertisement