Spring 自定義了繼承 JDK 事件監聽器的介面 ,用來監聽 Spring 應用程式中的事件;自定義了繼承 JDK 事件對象的抽象類 ,用來表示 Spring 應用程式中的事件類型。容器啟動刷新過程中,可以定義事件監聽器,來監聽應用程式上下文事件 ,它有四個具體的實現類: ,分別表示容器啟動/刷 ...
Spring 自定義了繼承 JDK 事件監聽器的介面ApplicationListener<E extends ApplicationEvent> extends EventListener
,用來監聽 Spring 應用程式中的事件;自定義了繼承 JDK 事件對象的抽象類ApplicationEvent extends EventObject
,用來表示 Spring 應用程式中的事件類型。容器啟動刷新過程中,可以定義事件監聽器,來監聽應用程式上下文事件ApplicationContextEvent extends ApplicationEvent
,它有四個具體的實現類:
ContextStartedEvent/ContextRefreshedEvent/ContextStoppedEvent/ContextClosedEvent
,分別表示容器啟動/刷新/停止/關閉的事件。
通常有兩種方式來實現 Spring 中的事件監聽:
1.實現 ApplicationListener 介面
public class MyListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("MyListener: " + event);
}
}
2.使用 @EventListener 註解
public class MyAnnotationListener {
@EventListener(classes = ApplicationEvent.class)
public void listen(ApplicationEvent event) {
System.out.println("@EventListener:" + event);
}
}
3.自定義發佈事件
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Test.class);
// 發佈事件
context.publishEvent(new ApplicationEvent("my event") {});
}
}
原理
在 Spring 容器啟動,調用 refresh() 刷新的過程中,會初始化事件派發器,並註冊事件監聽器,最後通過事件派發器,將事件發佈給自己的監聽器。
1 初始化事件派發器
initApplicationEventMulticaster();
為容器中的 BeanFactory 初始化一個事件派發器 (ApplicationEventMulticaster) :SimpleApplicationEventMulticaster,並註冊到 BeanFactory,name 為 applicationEventMulticaster。
2 添加 ApplicationListener 監聽器
registerListeners();
取出 BeanFactory 中 ApplicationListener 類型的事件監聽器,全部添加到上面的事件派發器的緩存中。
3 添加 @EventListener 監聽器
finishBeanFactoryInitialization(beanFactory)
從 Spring 後置處理器源碼 可知,Spring 初始化時會註冊 EventListenerMethodProcessor 和 DefaultEventListenerFactory。
EventListenerMethodProcessor 實現了 EventListenerMethodProcessor,所以執行 BeanFactory 後置處理器時,會調用 postProcessBeanFactory(),將 DefaultEventListenerFactory 添加到緩存中。
EventListenerMethodProcessor 實現了 SmartInitializingSingleton,所以在初始化剩餘的單例 Bean 之後,會調用 afterSingletonsInstantiated(),獲取所有的 BeanFactory,找到其中標註了 @EventListener 的方法,利用反射和 DefaultEventListenerFactory 為其創建 ApplicationListener,並添加到事件派發器的緩存中。
4 發佈事件
finishRefresh();
- 初始化生命周期處理器,註冊到 BeanFactory,name 為 lifecycleProcessor。
- 調用生命周期處理器的 onRefresh(),表示刷新狀態。
- 發佈上下文刷新事件。調用事件派發器的 multicastEvent() 進行派發,最終,通過回調事件監聽器的 onApplicationEvent() 方法,來通知監聽器。
非同步派發和異常處理器
- 如果事件派發器設置了 Executor,則可以進行非同步多線程的事件派發。
- 如果事件派發器設置了 ErrorHandler,則可以用異常處理器來處理異常。