Event Listeners

@EventListener

@Component
@Slf4j
public class LoyaltyListener {

    @EventListener
    public void onOrderPlaced(OrderPlacedEvent event) {
        int points = event.total().intValue() / 100;
        log.info("Awarding {} points to user {}", points, event.userId());
    }

    @EventListener(condition = "#event.total.compareTo(T(java.math.BigDecimal).valueOf(10000)) > 0")
    public void bigOrder(OrderPlacedEvent event) {
        log.info("Big order {}: flag for priority shipping", event.orderId());
    }
}

Example

curl -X POST localhost:8080/api/orders -H "Content-Type: application/json" -d '{"userId":7,"items":[{"productId":3,"quantity":1}]}'

Example output

INFO  LoyaltyListener : Awarding 549 points to user 7
INFO  LoyaltyListener : Big order 1001: flag for priority shipping

Synchronous by Default

  • Listeners run on the same thread, one after another, before publishEvent returns.
  • An exception in a listener propagates to the publisher (and can roll back its transaction).
  • Use @Order(1), @Order(2) on listener methods to control order.
  • A listener method can return another event object; Spring publishes it too.

Async Listeners

@Component
public class EmailListener {

    @Async("notificationExecutor")      // needs @EnableAsync
    @EventListener
    public void sendConfirmation(OrderPlacedEvent event) {
        emailClient.send(event.userId(), "Your order " + event.orderId() + " is confirmed");
    }
}

Tip: Make slow listeners (email, HTTP calls) @Async so the user does not wait. Keep fast, must-succeed logic synchronous.