События Spring

Базовый Spring
≈ 1 мин чтения

Сообщить о событии, не связывая классы напрямую

Иногда одна часть приложения должна сообщить: «что-то произошло», а другая — отреагировать. Можно вызвать нужный сервис напрямую, но тогда отправитель начинает знать о получателе. Spring Events позволяет ослабить эту связь.

record OrderCreated(long orderId) {
}

@Service
class OrderService {
    private final ApplicationEventPublisher publisher;

    OrderService(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    void create(long orderId) {
        publisher.publishEvent(new OrderCreated(orderId));
    }
}

@Component
class OrderCreatedListener {

    @EventListener
    void on(OrderCreated event) {
        System.out.println("Order: " + event.orderId());
    }
}

OrderService публикует факт создания заказа, но не знает, кто именно на него подпишется. Listener объявляет интерес к событию через @EventListener и получает объект события как аргумент.

Это события внутри приложения

Spring Events работают внутри одного ApplicationContext. Это не замена Kafka, RabbitMQ или другому брокеру сообщений. По умолчанию обработчики вызываются синхронно, поэтому публикация события и реакция listener происходят в одном потоке выполнения.

Событие должно описывать факт. Имя вроде OrderCreated лучше передаёт смысл, чем команда вроде SendEmailNow: отправитель сообщает, что произошло, а получатели сами решают, нужно ли реагировать.