上一節說了自定義事件及監聽的實現,這一節說下他的實現原理。
首先他發布事件使用過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事件