BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Spring and Boot

Spring

Spring application events

Events let one bean announce "something happened" without knowing who cares.

Learn these first

At a glance

Mental model

A bulletin board in an office: the person who posts a notice does not know who will read it, and readers do not need to know who posted it.

What happens, in order
  1. 1A bean publishes with publisher.publishEvent(new OrderPlaced(id))Every bean with an @EventListener method that accepts that type is called.
  2. 2By default listeners run synchronously in the publisher's thread, inside its transactionIf a listener throws, the publisher sees the exception.
  3. 3@TransactionalEventListener runs the listener at a chosen phase of the transaction, by default after it commits, which is the safe time for sending emails or messages about data that is really saved
Remember
Watch out
Expecting events to be asynchronous by defaultSending messages from a plain listener before the transaction commits (the data may be rolled back)Treating events as a durable queue
Example (highlighted lines explain it)
@Servicepublic class OrderService {    private final ApplicationEventPublisher events;    public OrderService(ApplicationEventPublisher events) { this.events = events; }    public void place(Order order) {        save(order);        events.publishEvent(new OrderPlaced(order.getId()));    }}@Componentclass EmailListener {    @EventListener    void on(OrderPlaced e) { log.info("send confirmation for {}", e.id()); }}
  1. line 3 uses ApplicationEventPublisher, the core of Spring application events
  2. line 4 uses ApplicationEventPublisher, the core of Spring application events
  3. line 8 uses publishEvent, the core of Spring application events
  4. line 14 uses EventListener, the core of Spring application events
Read the full explanation (about 1 min)

Events let one bean announce "something happened" without knowing who cares. Other beans listen with @EventListener and react, which keeps the parts of an application decoupled.

A mental model

A bulletin board in an office: the person who posts a notice does not know who will read it, and readers do not need to know who posted it.

How it works

A bean publishes with publisher.publishEvent(new OrderPlaced(id)). Every bean with an @EventListener method that accepts that type is called.

By default listeners run synchronously in the publisher's thread, inside its transaction. If a listener throws, the publisher sees the exception.

@TransactionalEventListener runs the listener at a chosen phase of the transaction, by default after it commits, which is the safe time for sending emails or messages about data that is really saved.

Going deeper

Events are in-process only: they do not cross services and are lost if the application stops. For reliable cross-service messaging use Kafka or a message broker, with an outbox table if the database write and the message must stay consistent.

An after-commit listener runs without an active transaction; if it needs to write to the database it must start a new one (REQUIRES_NEW).

Under the hood

The ApplicationContext is itself an ApplicationEventPublisher. EventListenerMethodProcessor registers each annotated method as a listener, and the multicaster calls the matching ones, optionally on an executor when one is configured.

Common mistakes

  • Expecting events to be asynchronous by default.
  • Sending messages from a plain listener before the transaction commits (the data may be rolled back).
  • Treating events as a durable queue.

How Unravel recognises it

When you paste code, Unravel looks for these signs of spring application events. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Spring application events?

Events let one bean announce "something happened" without knowing who cares. Other beans listen with @EventListener and react, which keeps the parts of an application decoupled.

What are the most common mistakes with Spring application events?

Expecting events to be asynchronous by default. Sending messages from a plain listener before the transaction commits (the data may be rolled back). Treating events as a durable queue.

How can I see Spring application events in real code?

Paste your own Java into Unravel and it will point out where spring application events appears, explain how it works at the detail level you choose, and draw the flow of the code around it.