spring之自定義事件及監聽 原理


上一節說了自定義事件及監聽的實現,這一節說下他的實現原理。

首先他發布事件使用過ApplicationContext.publishEvent()方法來實現,通過追蹤發現publishEvent()方法的實現是在AbstractApplicationContext抽象類中實現。

先捋請這幾個類的具體繼承和接口實現的層級關系。

eclipse下的:

 

然后再看AbstractApplicationContext下的publishEvent方法:

 1     /**
 2      * Publish the given event to all listeners.
 3      * @param event the event to publish (may be an {@link ApplicationEvent}
 4      * or a payload object to be turned into a {@link PayloadApplicationEvent})
 5      * @param eventType the resolved event type, if known
 6      * @since 4.2
 7      */
 8     protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
 9         Assert.notNull(event, "Event must not be null");
10 
11         // Decorate event as an ApplicationEvent if necessary
12         ApplicationEvent applicationEvent;
13         if (event instanceof ApplicationEvent) {
14             applicationEvent = (ApplicationEvent) event;
15         }
16         else {
17             applicationEvent = new PayloadApplicationEvent<>(this, event);
18             if (eventType == null) {
19                 eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
20             }
21         }
22 
23         // Multicast right now if possible - or lazily once the multicaster is initialized
24         if (this.earlyApplicationEvents != null) {
25             this.earlyApplicationEvents.add(applicationEvent);
26         }
27         else {
// SimpleApplicationEventMulticaster 獲取事件發布器,發布事件
28 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); 29 } 30 31 // Publish event via parent context as well... 32 if (this.parent != null) { 33 if (this.parent instanceof AbstractApplicationContext) { 34 ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); 35 } 36 else { 37 this.parent.publishEvent(event); 38 } 39 } 40 }
getApplicationEventMulticaster()代碼:
 1 /**
 2      * Return the internal ApplicationEventMulticaster used by the context.
 3      * @return the internal ApplicationEventMulticaster (never {@code null})
 4      * @throws IllegalStateException if the context has not been initialized yet
 5      */
 6     ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
 7         if (this.applicationEventMulticaster == null) {
 8             throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
 9                     "call 'refresh' before multicasting events via the context: " + this);
10         }
11         return this.applicationEventMulticaster;
12     }
ApplicationEventMulticaster 的multicastEvent()方法是在SimpleApplicationEventMulticaster類中實現。下面是層級結構圖。

SimpleApplicationEventMulticaster.multicastEvent()代碼
 1     @Override
 2     public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
 3         ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
// getApplicationListeners(event, type) 篩選監聽器,在context.publish(ApplicationEvent event)中已經將事件傳入,getApplicationListeners中將可以根據這個event類型從Spring容器中檢索出符合條件的監聽器
4 Executor executor = getTaskExecutor(); 5 for (ApplicationListener<?> listener : getApplicationListeners(event, type)) { 6 if (executor != null) { 7 executor.execute(() -> invokeListener(listener, event)); 8 } 9 else {
10 invokeListener(listener, event);//嘗試逐個向監聽器廣播 11 } 12 } 13 }

下面是進行debug的結果:

      

在multicastEvent發布完,就直接循環event事件


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM