Статьи
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.


Облако тэгов

Kotlin, Java, Java 16, Java 11, Java 10, Java 9, Java 8, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Hibernate, Collections, Stream API, многопоточность, файлы, Apache, maven, gradle, JUnit, YouTube, новости, руководство, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml.

Последние статьи


Комментарии

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

×

devmark.ru