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事件