5.2.6.11. Events
Бин Events
реализует функциональность публикации объектов-событий уровня приложения. События могут использоваться для передачи данных между слабо связанными компонентами приложения. Бин Events
является простым фасадом для объекта ApplicationEventPublisher
Spring Framework.
public interface Events {
String NAME = "cuba_Events";
void publish(ApplicationEvent event);
}
Этот бин имеет только один метод - publish()
, принимающий объект события. Метод Events.publish()
уведомляет все слушатели, зарегистрированные в приложении и подписанные на события того же типа, что и переданный объект. Вы может использовать класс-обёртку PayloadApplicationEvent
для публикации любых объектов в качестве событий.
См. также руководство Spring Framework.
- Обработка событий в компонентах приложения
-
Прежде всего, необходимо создать класс события. Он должен быть наследником класса
ApplicationEvent
. Класс события может включать любые дополнительные данные. Например:public class DemoEvent extends ApplicationEvent { public DemoEvent(User source) { super(source); } @Override public User getSource() { return (User) super.getSource(); } }
Бины могут публиковать события, используя бин
Events
:@Component public class DemoBean { @Inject private Events events; @Inject private UserSessionSource userSessionSource; public void demo() { UserSession userSession = userSessionSource.getUserSession(); events.publish(new DemoEvent(userSession.getUser())); } }
По умолчанию все события обрабатываются синхронно.
Есть два способа обработки событий:
-
Реализовать интерфейс
ApplicationListener
. -
Использовать аннотацию
@EventListener
для метода.
В первом случае, мы должны создать бин, реализующий интерфейс
ApplicationListener
с указанием типа события:@Component public class DemoEventListener implements ApplicationListener<DemoEvent> { @Inject private Logger log; @Override public void onApplicationEvent(DemoEvent event) { log.debug("Demo event is published"); } }
Второй способ может использоваться для сокрытия деталей реализации обработчика событий и обработки множества различных событий в одном бине:
@Component public class MultipleEventListener { @Order(10) @EventListener private void handleDemoEvent(DemoEvent event) { // handle event } @Order(1010) @EventListener private void handleUserLoginEvent(UserLoggedInEvent event) { // handle event } }
Вы можете использовать интерфейс
Ordered
и аннотацию@Order
Spring Framework для указания порядка исполнения обработчиков событий. Все бины и обработчики событий платформы используют значениеorder
от 100 до 1000, таким образом, вы можете добавить обработчик событий как до, так и после обработчиков события платформы. Если вы хотите добавить свой обработчик события до обработчиков из платформы, то используйте значение меньше 100.См. также События логина.
-
- Обработка событий в экранах
-
Обычно, бин
Events
делегирует публикацию события объектуApplicationContext
. Для блоков Web Client / Desktop Client это поведение отличается от стандартного, вы можете использовать дополнительный интерфейс для классов событий -UiEvent
. Это интерфейс-маркер для событий, которые должны быть доставлены в экраны пользовательского интерфейса текущего экземпляра UI (текущей вкладки веб-браузера). Важно отметить, что экземпляры событий, реализующихUiEvent
, не доставляются в бины Spring и не могут быть обработаны за пределами UI.Пример класса события:
public class UserRemovedEvent extends ApplicationEvent implements UiEvent { public UserRemovedEvent(User source) { super(source); } @Override public User getSource() { return (User) super.getSource(); } }
События публикуются при помощи бина
Events
из контроллера экрана так же, как и из бинов Spring:@Inject Events events; // ... UserRemovedEvent event = new UserRemovedEvent(removedUser); events.publish(event);
Чтобы обработать событие, вы должны объявить в экране метод с аннотацией
@EventListener
(ИнтерфейсApplicationListener
не поддерживается):@Order(15) @EventListener protected void onUserRemove(UserRemovedEvent event) { showNotification("User is removed " + event.getSource()); }
Вы можете использовать аннотацию
@Order
, чтобы задать порядок вызова обработчиков события.Если класс события реализует
UiEvent
, и объект такого события опубликован при помощи бинаEvents
из потока UI, то будут вызваны обработчики событий этого типа в открытых на данный момент окнах и фреймах. Обработка событий синхронная. Только экраны и фреймы текущей активной вкладки веб-браузера получат уведомление о событии.