Spring IoC контейнер: дополнительные возможности ApplicationContext, асинхронные слушатели, упорядочивание слушателей
Асинхронные слушатели
Если вы хотите, чтобы конкретный слушатель обрабатывал события асинхронно, вы можете повторно использовать обычную поддержку @Async. В следующем примере показано, как это сделать:
Java
@EventListener
@Async
public void processBlockedListEvent(BlockedListEvent event) {
// BlockedListEvent обрабатывается в отдельном потоке
}
Kotlin
@EventListener
@Async
fun processBlockedListEvent(event: BlockedListEvent) {
// BlockedListEvent обрабатывается в отдельном потоке
}
Помните о следующих ограничениях при использовании асинхронных событий:
- Если асинхронный прослушиватель событий выдает исключение, оно не передается вызывающей стороне.
- Методы асинхронного прослушивателя событий не могут публиковать последующее событие, возвращая значение. Если вам нужно опубликовать другое событие в результате обработки, введите ApplicationEventPublisher, чтобы опубликовать событие вручную.
Упорядочивание слушателей
Если вам нужно, чтобы один слушатель вызывался перед другим, вы можете добавить аннотацию @Order к объявлению метода, как показано в следующем примере:
Java
@EventListener
@Order(42)
public void processBlockedListEvent(BlockedListEvent event) {
// уведомляем соответствующие стороны через notificationAddress...
}
Kotlin
@EventListener
@Order(42)
fun processBlockedListEvent(event: BlockedListEvent) {
// уведомляем соответствующие стороны через notificationAddress...
}
Общие события
Вы также можете использовать универсальные шаблоны для дальнейшего определения структуры вашего события. Рассмотрите возможность использования EntityCreatedEvent<T>, где T - тип фактического созданного объекта. Например, вы можете создать следующее определение прослушивателя, чтобы получать только EntityCreatedEvent для Person:
Java
@EventListener
public void onPersonCreated(EntityCreatedEvent<Person> event) {
// ...
}
Kotlin
@EventListener
fun onPersonCreated(event: EntityCreatedEvent<Person>) {
// ...
}
Из-за стирания типа это работает только в том случае, если запускаемое событие разрешает общие параметры, по которым фильтруется прослушиватель событий (то есть что-то вроде class PersonCreatedEvent extends EntityCreatedEvent<Person> { … }).
В определенных обстоятельствах это может стать довольно утомительным, если все события следуют одной и той же структуре (как и должно быть в случае события в предыдущем примере). В таком случае вы можете реализовать ResolvableTypeProvider, чтобы направить структуру за пределы того, что предоставляет среда выполнения. Следующее событие показывает, как это сделать:
Java
public class EntityCreatedEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
public EntityCreatedEvent(T entity) {
super(entity);
}
@Override
public ResolvableType getResolvableType() {
return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getSource()));
}
}
Kotlin
class EntityCreatedEvent<T>(entity: T) : ApplicationEvent(entity), ResolvableTypeProvider {
override fun getResolvableType(): ResolvableType? {
return ResolvableType.forClassWithGenerics(javaClass, ResolvableType.forInstance(getSource()))
}
}
Это работает не только с ApplicationEvent, но и с любым произвольным объектом, который вы отправляете как событие.
Читайте также:
- Spring IoC контейнер: дополнительные возможности ApplicationContext, слушатели событий на основе аннотаций
- Spring IoC контейнер: дополнительные возможности ApplicationContext, интернационализация с использованием MessageSource
- Spring IoC контейнер: дополнительные возможности ApplicationContext, стандартные и специальные события
Комментарии
Отправить комментарий