java 43 lines · 8 steps

Decoupling side effects with Spring events

A service publishes a domain event and a listener reacts only after the transaction commits, keeping order placement independent from notifications.

Explained by highlit
1@Service
2public class OrderService {
3 
4 private final OrderRepository orderRepository;
5 private final ApplicationEventPublisher eventPublisher;
6 
7 public OrderService(OrderRepository orderRepository, ApplicationEventPublisher eventPublisher) {
8 this.orderRepository = orderRepository;
9 this.eventPublisher = eventPublisher;
10 }
11 
12 @Transactional
13 public Order placeOrder(PlaceOrderCommand command) {
14 Order order = new Order(command.customerId(), command.items());
15 order.markPlaced();
16 orderRepository.save(order);
17 
18 eventPublisher.publishEvent(new OrderPlacedEvent(order.getId(), order.getCustomerId(), order.getTotal()));
19 return order;
20 }
21}
22 
23public record OrderPlacedEvent(Long orderId, Long customerId, BigDecimal total) {
24}
25 
26@Component
27public class OrderPlacedListener {
28 
29 private static final Logger log = LoggerFactory.getLogger(OrderPlacedListener.class);
30 
31 private final NotificationService notificationService;
32 
33 public OrderPlacedListener(NotificationService notificationService) {
34 this.notificationService = notificationService;
35 }
36 
37 @Async
38 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
39 public void onOrderPlaced(OrderPlacedEvent event) {
40 log.info("Order {} placed for customer {} totalling {}", event.orderId(), event.customerId(), event.total());
41 notificationService.sendOrderConfirmation(event.customerId(), event.orderId());
42 }
43}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Publishing a domain event lets the core operation stay ignorant of who reacts to it.
  2. 2AFTER_COMMIT listeners ensure side effects only fire once the data is durably saved.
  3. 3Combining @Async with transactional listeners moves slow work off the request thread without risking phantom notifications.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Decoupling side effects with Spring events — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code