1.事件(ApplicationEvent)java
ApplicationEvent 是全部事件對象的父類。ApplicationEvent 繼承自 jdk 的 EventObject, 全部的事件都須要繼承 ApplicationEvent, 而且經過source獲得事件源。git
下列描述了Spring提供的內置事件:github
2.事件監聽(ApplicationListener)web
ApplicationListener 事件監聽器,也就是觀察者。繼承自 jdk 的 EventListener,該類中只有一個方法 onApplicationEvent。當監聽的事件發生後該方法會被執行。spring
3.事件發佈(ApplicationContext)app
ApplicationContext 是 Spring 中的核心容器,在事件監聽中 ApplicationContext 能夠做爲事件的發佈者,也就是事件源。由於 ApplicationContext 繼承自 ApplicationEventPublisher。在 ApplicationEventPublisher 中定義了事件發佈的方法 — publishEvent(Object event)異步
4.事件管理(ApplicationEventMulticaster)ide
ApplicationEventMulticaster 用於事件監聽器的註冊和事件的廣播。監聽器的註冊就是經過它來實現的,它的做用是把 Applicationcontext 發佈的 Event 廣播給它的監聽器列表。post
@TransactionalEventListener 監聽器:若是事件的發佈不是在事務(@Transactional)範圍內,則監聽不到該事件,除非將 fallbackExecution 標誌設置爲 true(@TransactionalEventListener(fallbackExecution = true));若是在事務中,能夠選擇在事務的哪一個階段來監聽事件,默認在事務提交後監聽(@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION))。單元測試
以上介紹的事件監聽都是同步,若是須要開啓異步支持的話:
@Configuration @EnableAsync public class AsyncEventConfiguration implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { return Executors.newCachedThreadPool(); } }
@Component public class MyEvent extends ApplicationEvent { public MyEvent(ApplicationContext source) { super(source); System.out.println("MyEvent 構造器執行"); } public void echo() { System.out.println("模擬業務邏輯執行"); } }
@Component public class MyListenerA implements ApplicationListener<MyEvent> { @Override public void onApplicationEvent(MyEvent myEvent) { System.out.println("MyListenerA"); myEvent.echo(); } }
@Component public class MyListenerB { @EventListener public void onApplicationEvent(MyEvent myEvent) { System.out.println("MyListenerB"); myEvent.echo(); } }
@Component public class MyPublisher implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } /** * 發佈事件 * 監聽該事件的監聽者均可以獲取消息 * * @param myEvent */ public void publisherEvent(MyEvent myEvent) { System.out.println("---開始發佈 myEvent 事件---"); applicationContext.publishEvent(myEvent); } }
@RunWith(SpringRunner.class) @SpringBootTest public class DesignPatternsApplicationTests { @Autowired private MyPublisher myPublisher; @Autowired private MyEvent myEvent; @Test public void contextLoads() { myPublisher.publisherEvent(myEvent); } }