深入理解Spring的容器内事件发布监听机制(5)

1.容器中已有id为applicationEventMulticaster的bean
直接从容器缓存获取或是创建该bean实例,并交由成员变量applicationEventMulticaster保存。
当用户自定义了事件发布器并向容器注册时会执行该流程。

2.容器中不存在applicationEventMulticaster的bean
这是容器默认的执行流程,会创建一个SimpleApplicationEventMulticaster,其仅在实现事件发布器基本功能(管理事件监听器以及发布容器事件)的前提下,增加了可以设置任务执行器
Executor和错误处理器ErrorHandler的功能,当设置Executor为线程池时,则会以异步的方式对事件监听器进行回调,而ErrorHandler允许我们在回调方法执行错误时进行自定义处理。默认情况下,
这两个变量都为null。

public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {

private Executor taskExecutor;

private ErrorHandler errorHandler;public abstract class AbstractApplicationEventMulticaster
      implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {

private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);

final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
        new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);

private ClassLoader beanClassLoader;

private BeanFactory beanFactory;

private Object retrievalMutex = this.defaultRetriever;

之后会调用beanFactory.registerSingleton方法将创建的SimpleApplicationEventMulticaster实例注册为容器的单实例bean。

初始化事件发布器的工作非常简单,一句话总结:由容器实例化用户自定义的事件发布器或者由容器帮我们创建一个简单的事件发布器并交由容器管理。

4.2 注册事件监听器流程

注册事件监听器的流程在初始化事件发布器之后,如下图所示

深入理解Spring的容器内事件发布监听机制

其关键代码如下所示

// uninitialized to let post-processors apply to them!
        //获取实现ApplicationListener接口的所有bean的beanName
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            //将监听器的beanName保存到事件发布器中
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

首先遍历beanFactory中所有的bean,获取所有实现ApplicationListener接口的bean的beanName,并将这些beanName注册到ApplicationEventMulticaster中

@Override
public void addApplicationListenerBean(String listenerBeanName) {
  synchronized (this.retrievalMutex) {
      //保存所有监听器的beanName
      this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
      //清除维护事件和监听器映射关系的缓存
      this.retrieverCache.clear();
  }
}

defaultRetriever是定义在抽象类AbstractApplicationEventMulticaster中的成员,用来保存所有事件监听器及其beanName

private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);

其以内部类形式定义在AbstractApplicationEventMulticaster中

/**
    * Helper class that encapsulates a specific set of target listeners,
    * allowing for efficient retrieval of pre-filtered listeners.
    * <p>An instance of this helper gets cached per event type and source type.
    */
    private class ListenerRetriever {

//保存所有事件监听器
        public final Set<ApplicationListener<?>> applicationListeners;

//保存所有事件监听器的beanName
        public final Set<String> applicationListenerBeans;

向事件发布器注册监听器的beanName,其实就是将beanName加入ListenerRetriever的集合中。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8aa7eccef7a6ee573b4af64ab1388374.html