事件機制spring
相關概念: 事件EventObject 事件生成器 事件的產生者,生成事件後,使用事件發佈器發佈事件。 事件生成器工廠 生產多種類型的事件生成器 事件發佈器EventPublisher 發佈事件:將事件發佈到廣播器中。 事件廣播器 通知在事件監聽器註冊表中註冊的事件監聽器。即將事件dispatch到對應的監聽器上。 事件監聽器EventListener 監聽事件,並作相應的處理。 事件監聽器註冊表 管理事件監聽器,廣播器經過註冊表來尋找指定的監聽器。 執行流程: 1)初始化監聽器註冊表。 2)businessService ---> 生成事件 ---> 發佈事件 ---> 廣播器:從註冊表中獲取指定類型的監聽器,並通知監聽器 ---> 各個監聽器響應該事件。
jdk的事件機制:數據結構
事件:EventObject 未定義事件發佈器 事件監聽器:EventListener
spring的事件機制:app
事件:ApplicationEvent 繼承了jdk的EventObject 事件生成器:spring中並無定義事件生成器,spring直接經過new ApplicationEvent的實現類來生成事件。 事件發佈器:ApplicationEventPublisher 實現: ApplicationContext繼承了ApplicationEventPublisher,即ApplicationContext的實現類做爲不一樣的事件發佈器。 將事件發佈到廣播器中:AbstractApplicationContext調用廣播器的multicastEvent()方法將事件發佈到廣播器中。 事件廣播器:ApplicationEventMulticaster 實現: 默認廣播器:SimpleApplicationEventMulticaster 使用multicastEvent()方法來廣播事件: 從註冊表中獲取監聽器:使用getApplicationListeners()方法從註冊表中獲取事件監聽器。 通知監聽器:使用invokeListener()方法來通知指定的監聽器,invokeListener()方法內調用了監聽器的onApplicationEvent方法。 事件監聽器:ApplicationListener 繼承了jdk的EventListener 事件監聽器註冊表: 實現: 數據結構:AbstractApplicationContext的applicationListeners屬性: private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>(); 註冊監聽器:經過AbstractApplicationContext的addApplicationListener()方法將監聽器添加到註冊表中。 初始化:容器啓動的時候,會初始化註冊表。 eg:在建立容器和初始化容器時會調用FrameworkServlet.configureAndRefreshWebApplicationContext()方法,該方法會調用addApplicationListener()方法來註冊監聽器。 說明: /** * ApplicationContext(更確切的說是AbstractApplicationContext)在spring的事件機制中扮演了多個角色:事件發佈器、事件廣播器、監聽器註冊表 */ public abstract class AbstractApplicationContext implements ApplicationContext { // ApplicationContext繼承了ApplicationEventPublisher,故AbstractApplicationContext即事件發佈器 // 事件廣播器 /** Helper class used in event publishing */ private ApplicationEventMulticaster applicationEventMulticaster; // 事件監聽器註冊表 private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>(); /** ApplicationEvents published early */ private Set<ApplicationEvent> earlyApplicationEvents; @Override public void addApplicationListener(ApplicationListener<?> listener) { if (this.applicationEventMulticaster != null) { this.applicationEventMulticaster.addApplicationListener(listener); } else { this.applicationListeners.add(listener); } } // 發佈事件 @Override public void publishEvent(ApplicationEvent event) { publishEvent(event, null); } protected void publishEvent(Object event, ResolvableType eventType) { // Decorate event as an ApplicationEvent if necessary ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent<Object>(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType(); } } // Multicast right now if possible - or lazily once the multicaster is initialized if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } // Publish event via parent context as well... if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } } } 舉例: duboo服務的導出: 監聽器:ServiceBean ServiceBean實現了spring的ApplicationListener接口,而且監聽着spring的上下文刷新事件(ContextRefreshedEvent),當監聽到spring的上下文刷新事件時,執行服務導出操做。