美文网首页
4-BeanFactory的增强:ApplicationCont

4-BeanFactory的增强:ApplicationCont

作者: 鹏程1995 | 来源:发表于2020-02-25 16:13 被阅读0次

概要

过度

上面我们宏观介绍了refresh()的基本思路:

1.png

接下来我们按照框出来的四个部分依次介绍,本节介绍的是Context的设置。

内容简介

本节介绍对context的设置,主要包括:

  1. 初始化MessageSource,目的是国际化和本土化的配置
  2. 初始化事件广播的相关组件
  3. 将配置的监听器进行注册

其中,我们主要关注的是整个ApplicationContext 的工作流程,所以主要对后两点进行介绍,后面如果涉及国际化和本土化的东西,再回头看。

所属环节

context相关设置。

上下环节

上文: 完成了对BeanFactory的设置

下文:刷新完成,对BeanFactory中所有的单例进行实例化以校验配置是否正确。并发布启动事件

源码解析

入口

还是从我们最开始的refresh()函数开始:

@Override
public void refresh() throws BeansException, IllegalStateException {
  synchronized (this.startupShutdownMonitor) {
    // Prepare this context for refreshing.
    // 准备此 ApplicationContext
    prepareRefresh();

    // Tell the subclass to refresh the internal bean factory.
    // BeanFactory 的初始化及对应的 BD 的加载
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    // Prepare the bean factory for use in this context.
    // 对 BeanFactory 中的一些和上下文相关的属性进行设置和同步。
    prepareBeanFactory(beanFactory);

    try {
      // Allows post-processing of the bean factory in context subclasses.
      // 定义了一个钩子,供子类实现
      postProcessBeanFactory(beanFactory);

      // Invoke factory processors registered as beans in the context.
      // 调用 BeanFactory 的后处理器对其进行处理
      invokeBeanFactoryPostProcessors(beanFactory);

      // Register bean processors that intercept bean creation.
      // 注册那些拦截 Bean 创建的后处理器
      // 注意,上面 invokeBeanFactoryPostProcessors() 各种实例化各种注册,操作的都是针对 factory 的后处理器。这里才是针对 bean
      // 的后处理器
      registerBeanPostProcessors(beanFactory);

      // Initialize message source for this context.
      // 初始化本 context 的 Message 源【国际化和本土化】【将对应的信息符号转化成对应的语言提示】
      // TODO 没啥需要,最后再看
      initMessageSource();

      // Initialize event multicaster for this context.
      // 初始化事件广播相关的东西
      initApplicationEventMulticaster();

      // Initialize other special beans in specific context subclasses.
      // 子实现类根据各自情况实现其他的特殊 Bean 的处理
      // 算是留下的一个钩子
      onRefresh();

      // Check for listener beans and register them.
      // 找出所有可注册的监听器并注册成有效的监听器,完成初始化后将之前缓存的事件散发出去
      registerListeners();

      // Instantiate all remaining (non-lazy-init) singletons.
      // 将剩余的非懒加载的单例加载一下
      finishBeanFactoryInitialization(beanFactory);

      // Last step: publish corresponding event.
      // 完成启动,散发相应事件
      finishRefresh();
    } catch (BeansException ex) {
      if (logger.isWarnEnabled()) {
        logger.warn("Exception encountered during context initialization - " +
                    "cancelling refresh attempt: " + ex);
      }

      // Destroy already created singletons to avoid dangling resources.
      destroyBeans();

      // Reset 'active' flag.
      cancelRefresh(ex);

      // Propagate exception to caller.
      throw ex;
    } finally {
      // Reset common introspection caches in Spring's core, since we
      // might not ever need metadata for singleton beans anymore...
      resetCommonCaches();
    }
  }
}

本节我们主要对initApplicationEventMulticaster(),registerListeners()进行介绍。

初始化事件广播组件

这里主要介绍initApplicationEventMulticaster()函数:

protected void initApplicationEventMulticaster() {
  ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  // 有自行定制就用 BeanFactory 中定制的,如果没有就用默认的。
  if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
    this.applicationEventMulticaster =
      beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    if (logger.isDebugEnabled()) {
      logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
    }
  } else {
    this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
    beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    if (logger.isDebugEnabled()) {
      logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                   APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                   "': using default [" + this.applicationEventMulticaster + "]");
    }
  }
}

思路就是如果在BeanFactory中有注册,就用注册的,如果没有,就用默认的实现自己生成一个。注意,自己补充上之后会在BeanFactory中注册,方便用户自己通过依赖注入获得。

注册事件监听器

// 我们之前把对应的监听器都放到 applicationListeners ,这里注册成正经发挥总用的监听器
// 当然,我们创建的 BD 里面类型合适的,也一同完成注册。完成注册后将积压的那些事件散发出去。
// 注意:对于在后面又增加的 BD ,context 增加了一个后处理器,发现是监听器的实例初始化了,也会自动给注册进去。
protected void registerListeners() {
  // Register statically specified listeners first.
  for (ApplicationListener<?> listener : getApplicationListeners()) {
    getApplicationEventMulticaster().addApplicationListener(listener);
  }

  // Do not initialize FactoryBeans here: We need to leave all regular beans
  // uninitialized to let post-processors apply to them!
  String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
  for (String listenerBeanName : listenerBeanNames) {
    getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  }

  // Publish early application events now that we finally have a multicaster...
  Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
  this.earlyApplicationEvents = null;
  if (earlyEventsToProcess != null) {
    for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
      getApplicationEventMulticaster().multicastEvent(earlyEvent);
    }
  }
}

将自己编码在ApplicationContext中的监听器注册,然后把BeanFactory中符合条件的也进行注册。

注意,前面在配置BeanFactory时加了一个后处理器,如果发现监听器类型的实例,会自动注册到上下文。由此保证所有的监听器都能被发现并将事件通知到位。

扩展

问题遗留

参考文献

相关文章

网友评论

      本文标题:4-BeanFactory的增强:ApplicationCont

      本文链接:https://www.haomeiwen.com/subject/hjotchtx.html