Статьи
Утилиты Telegram YouTube Отзывы

Работа с событиями в Spring

Видеогайд

6 ноября 2021

Тэги: Kotlin, rest, Spring, Spring Boot, YouTube.

Содержание

  1. Публикуем событие
  2. Обрабатываем событие
  3. Выводы

Spring «из коробки» предоставляет простой механизм работы с событиями, которые позволяют уменьшить связность компонентов системы. Событие, которое возникает в одной точке приложения, может быть перехвачено и обработано в любой другой части приложения благодаря таким сущностям как publisher и eventListener.

Для примера рассмотрим rest-приложение на Kotlin, в котором есть некий метод с бизнес-логикой. И мы хотим каждый вызов этого метода фиксировать. Чтобы не повышать связность кода и не делать явный вызов конкретного компонента, мы можем публиковать событие в нашей системе и любые компоненты, которые будут «прослушивать» тип такого события, смогут выполнить дополнительные действия.

Данный материал также доступен в формате видео на Youtube.

Публикуем событие

Создадим собственный тип события (data-класс), унаследовав его от стандартного класса ApplicationEvent.

data class BusinessEvent(
    val sourceObject: Any,
    val payload: String,
): ApplicationEvent(sourceObject)

У этого класса есть два поля:

  1. sourceObject для ссылки на объект, в котором возникло событие и который мы передаём в базовый класс события.
  2. payload – полезная мета-информация. В данном случае просто кидаем строку текста.

Теперь нам осталось подтянуть стандартный компонент ApplicationEventPublisher в нужную нам точку приложения и опубликовать через него наше событие. Бизнесовый метод может выглядеть так:

@RestController
class BusinessController(
    val publisher: ApplicationEventPublisher,
) {
    @PostMapping
    fun create() {
        // бизнес-логика

        val event = BusinessEvent(
            sourceObject = this,
            payload = "Some information"
        )
        publisher.publishEvent(event)
    }
}

Здесь после выполнения бизнес-логики нашего метода выполняем публикацию события, которое содержит какую-то полезную информацию.

Для краткости здесь обработка происходит в контроллере, однако в реальных проектах вся бизнес-логика должна быть инкапсулирована в сервисном слое.

Обрабатываем событие

Теперь создадим сервис аудита, который будет «слушать» событие. Его интерфейс может выглядеть так:

interface AuditService {
    fun onBusinessEvent(event: BusinessEvent)
}

Тогда реализация примет следующий вид:

@Service
class AuditServiceImpl : AuditService {

    private val logger = LoggerFactory.getLogger(AuditServiceImpl::class.java)

    @EventListener(BusinessEvent::class)
    override fun onBusinessEvent(event: BusinessEvent) {
        logger.info("Business event received: $event")
    }
}

Мы можем повесить на любой метод аннотацию @EventListener и указать тип события, которое метод должен перехватывать. Разумеется, метод в качестве параметра должен принимать именно этот тип.

В нашем примере мы перехватываем событие типа BusinessEvent и просто пишем в лог его содержимое. При этом любые другие события, возникающие в системе, мы перехватывать не будем.

Выводы

Spring позволяет легко реализовать простейшую событийную модель в приложении. Прежде всего это снижает связность отдельных компонентов системы между собой. В дальнейшем такая архитектура позволит легко перейти на более «серьёзные» решения вроде полноценных очередей RabbitMQ или Kafka.



Комментарии

Добавить комментарий

×

devmark.ru