3. Spring ApplicationListener源码版

ApplicationListener系列文章

  1. ApplicationListener 基础版

  2. ApplicationListener 进阶版

  3. ApplicationListener源码版

  4. ApplicationListener 问题版

  5. ApplicationListener 扩展版

  6. ApplicationListener 总结版

入口

AbstractApplicationContext

org.springframework.context.support.AbstractApplicationContext#publishEvent(java.lang.Object)

@Override
public void publishEvent(ApplicationEvent event) {
   publishEvent(event, null);
}

/**发送事件*/
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
   Assert.notNull(event, "Event must not be null");

   // Decorate event as an ApplicationEvent if necessary
   ApplicationEvent applicationEvent;
   if (event instanceof ApplicationEvent) {
      applicationEvent = (ApplicationEvent) event;
   }
   else {
      applicationEvent = new PayloadApplicationEvent<>(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);
      }
   }
}

广播事件

SimpleApplicationEventMulticaster

SimpleApplicationEventMulticaster:简单的事件广播实现,multicastEvent方法。

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
   ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
   //线程池,setTaskExecutor就可以实现异步处理了!!!
   Executor executor = getTaskExecutor();
   //根据Event和type,获取对应的Listener,其实主要是Event判断获取,存在多个情景,
   //此时就会存在,如果Listner执行监听业务失败,导致其他Listener无法执行
   for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      if (executor != null) {
         //没有设置线程池,忽略。如果用线程池,就没有一个监听执行失败,影响其他监听的场景了
         //因为线程池,天生会吃掉异常。
         executor.execute(() -> invokeListener(listener, event));
      }
      else {   
         //调用Listener
         invokeListener(listener, event);
      }
   }
}

/**实际调用Listener*/
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
   ErrorHandler errorHandler = getErrorHandler();
   //errorHandler也是没有定义,忽略
   if (errorHandler != null) {
      try {
         doInvokeListener(listener, event);
      }
      catch (Throwable err) {
         errorHandler.handleError(err);
      }
   }
   else {
      //实际的执行
      doInvokeListener(listener, event);
   }
}

/**执行了*/
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
   try {
      //onApplicationEvent,这就是自定义Listener的实现接口
      listener.onApplicationEvent(event);
   }
   catch (ClassCastException ex) {
      String msg = ex.getMessage();
      if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
         // Possibly a lambda-defined listener which we could not resolve the generic event type for
         // -> let's suppress the exception and just log a debug message.
         Log logger = LogFactory.getLog(getClass());
         if (logger.isTraceEnabled()) {
            logger.trace("Non-matching event type for listener: " + listener, ex);
         }
      }
      else {
         throw ex;
      }
   }
}

根据Event获取Listener

AbstractApplicationEventMulticaster

org.springframework.context.event.AbstractApplicationEventMulticaster#getApplicationListeners(org.springframework.context.ApplicationEvent, org.springframework.core.ResolvableType)

/**根据事件,获取对应的监听*/
protected Collection<ApplicationListener<?>> getApplicationListeners(
      ApplicationEvent event, ResolvableType eventType) {

   Object source = event.getSource();
   Class<?> sourceType = (source != null ? source.getClass() : null);
   //缓存key,根据ListenerKey的equals方法,可以推测出Listener与Event的映射关系
   ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

   // Quick check for existing entry on ConcurrentHashMap...
   ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
   if (retriever != null) {
      return retriever.getApplicationListeners();
   }

   if (this.beanClassLoader == null ||
         (ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
               (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
      // Fully synchronized building and caching of a ListenerRetriever
      synchronized (this.retrievalMutex) {
         retriever = this.retrieverCache.get(cacheKey);
         if (retriever != null) {
            return retriever.getApplicationListeners();
         }
         retriever = new ListenerRetriever(true);
         Collection<ApplicationListener<?>> listeners =
               retrieveApplicationListeners(eventType, sourceType, retriever);
         this.retrieverCache.put(cacheKey, retriever);
         return listeners;
      }
   }
   else {
      // No ListenerRetriever caching -> no synchronization necessary
      return retrieveApplicationListeners(eventType, sourceType, null);
   }
}

//获取监听器的核心方法
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
      ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {

   List<ApplicationListener<?>> allListeners = new ArrayList<>();
   Set<ApplicationListener<?>> listeners;
   Set<String> listenerBeans;
   synchronized (this.retrievalMutex) {
      listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
      listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
   }

   // Add programmatically registered listeners, including ones coming
   // from ApplicationListenerDetector (singleton beans and inner beans).
   for (ApplicationListener<?> listener : listeners) {
       //判断当前当前监听,是否支持该Event和Source
      if (supportsEvent(listener, eventType, sourceType)) {
         if (retriever != null) {
            retriever.applicationListeners.add(listener);
         }
         allListeners.add(listener);
      }
   }

   // Add listeners by bean name, potentially overlapping with programmatically
   // registered listeners above - but here potentially with additional metadata.
   if (!listenerBeans.isEmpty()) {
      ConfigurableBeanFactory beanFactory = getBeanFactory();
      for (String listenerBeanName : listenerBeans) {
         try {
            if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
               ApplicationListener<?> listener =
                     beanFactory.getBean(listenerBeanName, ApplicationListener.class);
               if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
                  if (retriever != null) {
                     if (beanFactory.isSingleton(listenerBeanName)) {
                        retriever.applicationListeners.add(listener);
                     }
                     else {
                        retriever.applicationListenerBeans.add(listenerBeanName);
                     }
                  }
                  allListeners.add(listener);
               }
            }
            else {
               // Remove non-matching listeners that originally came from
               // ApplicationListenerDetector, possibly ruled out by additional
               // BeanDefinition metadata (e.g. factory method generics) above.
               Object listener = beanFactory.getSingleton(listenerBeanName);
               if (retriever != null) {
                  retriever.applicationListeners.remove(listener);
               }
               allListeners.remove(listener);
            }
         }
         catch (NoSuchBeanDefinitionException ex) {
            // Singleton listener instance (without backing bean definition) disappeared -
            // probably in the middle of the destruction phase
         }
      }
   }

   AnnotationAwareOrderComparator.sort(allListeners);
   if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
      retriever.applicationListeners.clear();
      retriever.applicationListeners.addAll(allListeners);
   }
   return allListeners;
}

supportsEvent

protected boolean supportsEvent(
      ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
   //普通的监听,都是实现ApplicationListener,因此还需要通过适配器转换。
   GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
         (GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
   return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}

GenericApplicationListenerAdapter

监听器的适配,supportEevent主要通过该方法进行处理。

事件类型是否匹配
public boolean supportsEventType(ResolvableType eventType) {
   if (this.delegate instanceof SmartApplicationListener) {
      Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
      return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
   }
   else {
      return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
   }
}

事件比较的核心:this.declaredEventType.isAssignableFrom*(eventType)),即:ResolvableType的类型比较*

ResolvableType
public boolean isAssignableFrom(ResolvableType other) {
   return isAssignableFrom(other, null);
}

//实际比较
private boolean isAssignableFrom(ResolvableType other, @Nullable Map<Type, Type> matchedBefore) {
   Assert.notNull(other, "ResolvableType must not be null");

   // If we cannot resolve types, we are not assignable
   if (this == NONE || other == NONE) {
      return false;
   }

   // Deal with array by delegating to the component type
   if (isArray()) {
      return (other.isArray() && getComponentType().isAssignableFrom(other.getComponentType()));
   }

   if (matchedBefore != null && matchedBefore.get(this.type) == other.type) {
      return true;
   }

   // Deal with wildcard bounds
   WildcardBounds ourBounds = WildcardBounds.get(this);
   WildcardBounds typeBounds = WildcardBounds.get(other);

   // In the form X is assignable to <? extends Number>
   if (typeBounds != null) {
      return (ourBounds != null && ourBounds.isSameKind(typeBounds) &&
            ourBounds.isAssignableFrom(typeBounds.getBounds()));
   }

   // In the form <? extends Number> is assignable to X...
   if (ourBounds != null) {
      return ourBounds.isAssignableFrom(other);
   }

   // Main assignability check about to follow
   boolean exactMatch = (matchedBefore != null);  // We're checking nested generic variables now...
   boolean checkGenerics = true;
   Class<?> ourResolved = null;
   if (this.type instanceof TypeVariable) {
      TypeVariable<?> variable = (TypeVariable<?>) this.type;
      // Try default variable resolution
      if (this.variableResolver != null) {
         ResolvableType resolved = this.variableResolver.resolveVariable(variable);
         if (resolved != null) {
            ourResolved = resolved.resolve();
         }
      }
      if (ourResolved == null) {
         // Try variable resolution against target type
         if (other.variableResolver != null) {
            ResolvableType resolved = other.variableResolver.resolveVariable(variable);
            if (resolved != null) {
               ourResolved = resolved.resolve();
               checkGenerics = false;
            }
         }
      }
      if (ourResolved == null) {
         // Unresolved type variable, potentially nested -> never insist on exact match
         exactMatch = false;
      }
   }
   if (ourResolved == null) {
      ourResolved = resolve(Object.class);
   }
   Class<?> otherResolved = other.toClass();

   // We need an exact type match for generics
   // List<CharSequence> is not assignable from List<String>
   //比较的核心,第一次比较事件的Class是否一致:!ClassUtils.isAssignable(ourResolved, otherResolved)
   //如果一致,判断是否具有泛型,然后比较相关的泛型。
   if (exactMatch ? !ourResolved.equals(otherResolved) : !ClassUtils.isAssignable(ourResolved, otherResolved)) {
      return false;
   }

   if (checkGenerics) {
      // Recursively check each generic
      ResolvableType[] ourGenerics = getGenerics();
      ResolvableType[] typeGenerics = other.as(ourResolved).getGenerics();
      if (ourGenerics.length != typeGenerics.length) {
         return false;
      }
      if (matchedBefore == null) {
         matchedBefore = new IdentityHashMap<>(1);
      }
      matchedBefore.put(this.type, other.type);
      for (int i = 0; i < ourGenerics.length; i++) {
          //获取事件的所有泛型,意义比较
         if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], matchedBefore)) {
            return false;
         }
      }
   }

   return true;
}
数据类型是否匹配
@Override
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
   return !(this.delegate instanceof SmartApplicationListener) ||
         ((SmartApplicationListener) this.delegate).supportsSourceType(sourceType);
}

因为GenericApplicationListenerAdapter extends SmartApplicationListener,而SmartApplicationListener的supportesSourceType默认返回True,因此数据类型匹配永远为true。

注册监听

通过事件广播的源码跟踪,我们发现AbstractApplicationEventMulticaster.retrieveApplicationListeners方法中有如下代码:

synchronized (this.retrievalMutex) {
   listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
   listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}

非常好奇:this.defaultRetriever.applicationListeners,从哪儿来的,怎么就直接有数据了?

经过追踪,发现:org.springframework.context.support.ApplicationListenerDetector最终注册ApplicationListener。

ApplicationListenerDetector

ApplicationListenerDetector实现了BeanPostProcessor,因此可以针对每个bean,进行判断处理,并进行注册。

/**DestructionAwareBeanPostProcessor:对象销毁前的操作,从监听器中移除该监听,可以忽略
* 核心是MergedBeanDefinitionPostProcessor和BeanPostProcessor的方法。
*/
class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {

   private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class);

   private final transient AbstractApplicationContext applicationContext;

   private final transient Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);


   public ApplicationListenerDetector(AbstractApplicationContext applicationContext) {
      this.applicationContext = applicationContext;
   }


   @Override
   public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
      if (ApplicationListener.class.isAssignableFrom(beanType)) {
         //当前监听是否是单例
         this.singletonNames.put(beanName, beanDefinition.isSingleton());
      }
   }

   @Override
   public Object postProcessBeforeInitialization(Object bean, String beanName) {
      return bean;
   }

   @Override
   public Object postProcessAfterInitialization(Object bean, String beanName) {
      if (bean instanceof ApplicationListener) {
         // potentially not detected as a listener by getBeanNamesForType retrieval
         Boolean flag = this.singletonNames.get(beanName);
         if (Boolean.TRUE.equals(flag)) {
            //只有单例才能转化为监听,这就是注册监听器的位置
            // singleton bean (top-level or inner): register on the fly
            this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
         }
         else if (Boolean.FALSE.equals(flag)) {
            if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
               // inner bean with other scope - can't reliably process events
               logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
                     "but is not reachable for event multicasting by its containing ApplicationContext " +
                     "because it does not have singleton scope. Only top-level listener beans are allowed " +
                     "to be of non-singleton scope.");
            }
            this.singletonNames.remove(beanName);
         }
      }
      return bean;
   }

   @Override
   public void postProcessBeforeDestruction(Object bean, String beanName) {
      if (bean instanceof ApplicationListener) {
         try {
            ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
            multicaster.removeApplicationListener((ApplicationListener<?>) bean);
            multicaster.removeApplicationListenerBean(beanName);
         }
         catch (IllegalStateException ex) {
            // ApplicationEventMulticaster not initialized yet - no need to remove a listener
         }
      }
   }

   @Override
   public boolean requiresDestruction(Object bean) {
      return (bean instanceof ApplicationListener);
   }


   @Override
   public boolean equals(@Nullable Object other) {
      return (this == other || (other instanceof ApplicationListenerDetector &&
            this.applicationContext == ((ApplicationListenerDetector) other).applicationContext));
   }

   @Override
   public int hashCode() {
      return ObjectUtils.nullSafeHashCode(this.applicationContext);
   }

}

addApplicationListener

@Override
public void addApplicationListener(ApplicationListener<?> listener) {
   Assert.notNull(listener, "ApplicationListener must not be null");
   if (this.applicationEventMulticaster != null) {
      this.applicationEventMulticaster.addApplicationListener(listener);
   }
   this.applicationListeners.add(listener);
}

正式的加入applicationEventMulticaster中。

事件转发器

在“入口”章节,我们就提到,发布事件后,需要通过getApplicationEventMulticaster()获取转发器,然后multicastEvent,点击转发方法,默认跳转到SimpleApplicationEventMulticaster,那么什么时候注入的呢?

在AbstractApplicationContext中有字段,private ApplicationEventMulticaster applicationEventMulticaster;根据调用轨迹:org.springframework.context.support.AbstractApplicationContext#refresh中存在初始化ApplicationEventMulticaster的方法。

refresh.initApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   //如果已经有自定义的ApplicationMulticaster,直接使用自定义的
   if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
      this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
      if (logger.isTraceEnabled()) {
         logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
      }
   }
   else {
      //没有,默认初始化SimpleApplicationEventMulticaster
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
      if (logger.isTraceEnabled()) {
         logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
               "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
      }
   }
}

因此在广播事件时,multicastEvent方法,默认跳转到:SimpleApplicationEventMulticater类。

自定义事件转发器

在SimpleApplicationEventMulticaster的multicastEvent方法中,就发现支持线程池,因此可以自定义事件转发器,配置线程池,就能实现异步处理了。

生效位置

在refresh方法中,必须在initApplicationEventMulticaster执行前,就初始化好相关的事件转发器,因此只能通过BeanFactoryPostProcessor实现相关功能。

异步事件转发器

继承SimpleApplicationEventMulticaster,通过setTaskExecutor设置线程池。

public class AsyncApplicationEventMulticaster extends SimpleApplicationEventMulticaster {
    public AsyncApplicationEventMulticaster(BeanFactory beanFactory) {
        super(beanFactory);
        //自定义线程池,也可以通过配置信息,配置线程池
        Executor executor = new ThreadPoolExecutor(1, 5,
                10, TimeUnit.MINUTES,
                new ArrayBlockingQueue<>(1000),
                new ThreadFactory() {
                    @Override
                    public Thread newThread(Runnable r) {
                        Thread t = new Thread(r);
                        t.setName("applicationEvent_" + t.getName());
                        return t;
                    }
                }, new ThreadPoolExecutor.CallerRunsPolicy());
        setTaskExecutor(executor);
    }
}

注册异步事件转发器

实现BeanFactoryPostProcessor,进行异步事件转发器的注入。

public class AsyncApplicationEventMulticasterBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        if (!beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            //未定义相关的事件转发器
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
                    new AsyncApplicationEventMulticaster(beanFactory));
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值