SpringBoot源码学习(七)

时间:2022-07-25
本文章向大家介绍SpringBoot源码学习(七),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

通过前期的学习,我们发现在onRefresh方法之前的操作都是准备工作。在onRefresh方法之前的准备工作中,目前就剩下initApplicationEventMulticaster方法了。因为通过invokeBeanFactoryPostProcessors方法之后,所有需要的类均已经注册到beanDefinitionMap中,所以这块也应该是从beanDefinitionMap中获取特定接口的类并进行相关的操作。

从字面意思看,initApplicationEventMulticaster方法就是初始化一些广播器。通过之前的分析。在onRefresh方法之前的都是对beanFactory工厂的一些辅助。那么这里的init也应该是初始化beanFactory中的广播器。那么怎么初始化?那么应该和之前的beanPostProcessors是一样的,都需要通过beanDefinitionMap解析再获取实例化bean然后进行注册。

既然如此猜想,那就让我们走进看看吧!

  protected void initApplicationEventMulticaster() {
  //获取beanFactory工厂
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    //是否已经存在
    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 {
    //新创建一个,然后注册到beanFactory中
      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() + "]");
      }
    }
  }

我们看到这里也是直接创建一个SimpleApplicationEventMulticaster然后直接扔进IOC容器中并自己保留一份。

那么我们看看这里的SimpleApplicationEventMulticaster是何方神圣。

看到这里有线程工具和ErrorHandler,除此之外,还有很多方法比如doInvoke等。显然这里的类具有的作用就是执行。上边只是注册这个bean,那么后边肯定会有执行。那么这里的执行都是怎么执行的,还有他执行的条件是什么。

  @Override
  public void multicastEvent(ApplicationEvent event) {
    multicastEvent(event, resolveDefaultEventType(event));
  }
  
    @Override
  public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    //获取所有的监听器
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      //拿到线程池执
      Executor executor = getTaskExecutor();
      if (executor != null) {
        //广播实践
        executor.execute(() -> invokeListener(listener, event));
      }
      else {
      //广播
        invokeListener(listener, event);
      }
    }
  }
  
  
  //获取application类的实体
    protected Collection<ApplicationListener<?>> getApplicationListeners(
      ApplicationEvent event, ResolvableType eventType) {

    Object source = event.getSource();
    Class<?> sourceType = (source != null ? source.getClass() : null);
    ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

    //从initApplicationEventMulticaster注册的retrieverMux中获取
    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)))) {
      // 加锁,retrievalMutex是beanFactory中的单例bean缓存。显然这块也是在onRefresh之后执行的
      synchronized (this.retrievalMutex) {
        retriever = this.retrieverCache.get(cacheKey);
        if (retriever != null) {
        //拿到需要的Listner
          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);
    }
  } 

通过跟踪,发现这里的监听器的添加是在onrefresh之后的reginsterlistners方法中。

  //注册监听器
  protected void registerListeners() {
    // 获取监听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
    }
    //从beanfactories中获取监听器
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
      //添加到content中的属性中
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    //拿到earlyApplicationEvents
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
      //广播消息
        getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
    }
  }

通过上述分析,initApplicationEventMulticaster其实只是做了简单的初始化。并没有相关的功能实现。具体的广播事件其实是在IOC启动中调度的。注意这里是ApplicationListener接口的类。也就是这里获取都是实现了ApplicationListener接口的类。也就是说如果我们实现了ApplicationListener接口,然后调用multicastEvent方法就可以将我们的事件广播出去。但是这里multicastEvent谁可以调?我们看一下content的继承关系图谱。

发现有一个ApplicationEventPublisher,这是一个事件发布器。其中两个方法均为发布事件的。

我们看一下它的实现类。发现这里是有调用的。也就是说只要拿到了content,就可以将消息发布出去进行广播。

总结:在initApplicationEventMulticaster方法中,spring其实就是只是初始化了一个广播的中间类并放到ioc中并在自己哪里留存引用。真正向其中添加广播监听器是在onRefresh之后的registerListeners方法。而真正触发multicastEvent的方式是在content中调用publishEvent方法。