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

4-BeanFactory的增强:ApplicationCont

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

概要

过度

我们前面介绍了使用ApplicationContext的原因,并提出了一个新的实例。我们现在从那个实例入手,对ApplicationContext的整体实现逻辑做一个梳理介绍。

内容简介

梳理ApplicationContext整体思路。

所属环节

ApplicationContext整体思路梳理

上下环节

上文: ApplicationContext引入

下文: ApplicaitonContext中的各个环节,进入进行详细介绍

源码解析

入口

public class MyApplicationContextTest {
    public static void main(String[] args){
        ApplicationContext context = new ClassPathXmlApplicationContext("");
        context.getBean("");
    }
}

我们从这个例子开始入手。根据我们最开始的引入介绍很容易想到,ApplicationContext中大部分的附加是对BeanFactory中提供的各种配置,针对用户的使用场景进行了配置。

所以我们重点关注的其实是ApplicationContext context = new ClassPathXmlApplicationContext("");这一行。我们接下来进去看一下

外层逻辑介绍

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
  this(new String[]{configLocation}, true, null);
}

public ClassPathXmlApplicationContext(
  String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
  throws BeansException {

  super(parent);
  setConfigLocations(configLocations);
  if (refresh) {
    refresh();
  }
}

我们很容易发现:其实包含了两步,一是存储了配置文件的信息,二是调用了一个刷新函数,在这个函数中肯定存在了对BeanFactory的功能补充和ApplicationContext的初始化配置。

refresh()

// TODO 模版方法
@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();
    }
  }
}

思路比较明晰,一条线走下来:

1.png

后面我们会专门针对所有的步骤进行一一解读。

扩展

问题遗留

参考文献

相关文章

网友评论

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

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