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事件
posted @ 2019-12-13 17:10  风中之烛_清  阅读(902)  评论(0编辑  收藏  举报