← All articles
Backend1 min read

Event-Driven Design with Spring Application Events

Before reaching for Kafka, Spring's in-process application events can decouple your components cleanly. Here's when and how to use them.

S

Swapnika Voora

Author

Not every decoupling problem needs a message broker. Spring's application events let one component publish a fact and others react — all in-process, all type-safe, with no infrastructure to run.

Define and publish an event

An event is just an immutable object. Publish it through the ApplicationEventPublisher.

OrderService.java
public record OrderPlaced(Long orderId, BigDecimal total) {}
 
@Service
public class OrderService {
 
    private final ApplicationEventPublisher events;
 
    @Transactional
    public void place(Order order) {
        repository.save(order);
        events.publishEvent(new OrderPlaced(order.getId(), order.getTotal()));
    }
}

Listen without coupling

Any bean can react with @EventListener. The publisher has no idea who's listening, which keeps concerns separated.

Listeners.java
@Component
public class Listeners {
 
    @EventListener
    public void sendReceipt(OrderPlaced event) {
        email.sendReceipt(event.orderId());
    }
 
    @EventListener
    public void updateMetrics(OrderPlaced event) {
        metrics.recordSale(event.total());
    }
}

Wait for the commit

Reacting before the transaction commits risks acting on data that gets rolled back. @TransactionalEventListener fires only after a successful commit.

afterCommit.java
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void onCommitted(OrderPlaced event) {
    analytics.track(event);
}

Takeaways

  • Application events decouple components without extra infrastructure.
  • Multiple listeners can react to one event independently.
  • Use @TransactionalEventListener to act only after a commit succeeds.

When listeners need durability, retries, or cross-service delivery, that's your signal to graduate to Kafka or RabbitMQ.

#java#spring-boot#events#architecture

More in Backend