Spring源码解析三 (IOC容器初始化方式二:ClassPathXmlApplicationContext)

目录

1. 刷新, 获取Bean工厂

1.1 Bean工厂的刷新以及相关配置

1.2 BeanDefinition的预加载

2. 注册BeanDefinition

2.1 默认命名空间解析

2.1.1 标签处理解析

2.1.2 BeanDefinition的注册

2.2 自定义命名空间解析

2.2.1 获取名称处理器

2.2.2 根据标签名称获取解析器

2.2.3 解析自定义标签

3. Bean工厂配置的设置

4. 激活Bean工厂后处理器

5. 注册bean后处理处理器

6. 初始化非延迟加载的的单例Bean (延迟加载的单例将在第一次调用的时候初始化)

7. 应用上下文刷新结束, 进行事件广播


使用示例:

ApplicationContext applicationContext1 = new ClassPathXmlApplicationContext("springConf.xml");
UserService userService1 = (UserService) applicationContext1.getBean("userService");
userService1.query();

分析:

  1. 实例化ClassPathXmlApplicationContext示例,  使用接口ApplicationContext接收
  2. 调用getBean()获取bean
  3. 执行目标bean的方法

ClassPathXmlApplicationContext#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()方法 <经典的模板方法模式>
       */
      refresh();
   }
}

分析:

  1. 设置父类上下文信息
  2. 设置资源位置
  3. 调用父类AbstractApplicationContext的refresh()方法初始化容器 (重点)

AbstractApplicationContext#refresh实现 <核心方法>:

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // 准备好刷新上下文(设置一些变量)
      prepareRefresh();

      /**
       * obtainFreshBeanFactory()方法中根据实现类的不同调用不同的refreshBeanFactory()方法
       * <-----  注解模式  ----->
       * 1. 如果是使用AnnotationConfigApplicationContext来初始化环境
       * 调用的是GenericApplicationContext#refreshBeanFactory()方法
       * {@link GenericApplicationContext#refreshBeanFactory()}
       * 在该方法中只是对beanFactory的一些变量进行设置
       * <----- XML配置模式  ----->
       *  2. 如果是使用ClassPathXmlApplicationContext来初始化环境
       * 调用的是{@link AbstractRefreshableApplicationContext#refreshBeanFactory()}
       * 由于还没有对beanFactory进行初始化,所以在该方法中,完成了对beanFactory的初始化操作
       * 并对设置的资源位置进行扫描, 解析
       * 注意:此方法是使用ClassPathXmlApplicationContext来初始化上下文是解析注册bean的重要入口   <-------------------重要
       */
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      //对beanFactory进行属性设置
      prepareBeanFactory(beanFactory);

      try {
         //允许在子类中对bean工厂进行后处理。
         postProcessBeanFactory(beanFactory);

         /**
          * <-----  注解模式  ----->
          * 1. 如果是使用AnnotationConfigApplicationContext来初始化环境(该方法是解析注册bean的重要入口) <--------------------重要
          * 在该方法中执行了
          *     {@link org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions} 方法
          *     对配置类进行解析(如果该注解bean是配置类则在这个方法里完成了包扫描操作)          <--------------- 重要

          * 注意:
          *      1. 一般情况下, 此时beanFactory中只注册了这一个BeanFactoryPostProcessor类-->ConfigurationClassPostProcessor
          *     在{@link AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)}中注册的
          *     2. 注解模式下,此时BeanDefinitionMap中含有6个Spring内部处理器类, 其中通过ConfigurationClassPostProcessor类来解析配置类,完成包扫描,bean注册等操作
          *     然而, 在xml配置模式下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息
          *
          * <----- XML配置模式  ----->
          * 2. 如果是使用ClassPathXmlApplicationContext来初始化环境
          *  默认情况下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息, 并没有任何Spring内部所定义的BeanFactory后处理器
          *  除非用户自定义了BeanFactory后处理器, 需要对BeanFactory进行修改, 那么才会执行对应后处理器里面的方法;
          *
          */
         invokeBeanFactoryPostProcessors(beanFactory);

         //注册拦截bean创建的bean后处理处理器。
         registerBeanPostProcessors(beanFactory);

         //为上下文初始化Message源,即不同的语言体,国际化处理
         initMessageSource();

         // 初始化应用消息广播,并放入"appliactionEventMulitcaster"bean中
         initApplicationEventMulticaster();

         // 留给子类来初始化其他的Bean
         onRefresh();

         //在所有注册的bean中查找listener bean,注册到消息广播器中
         registerListeners();

         // 初始化剩下的单例(非延迟加载的,延迟加载的单例在第一次调用的时候初始化)
         finishBeanFactoryInitialization(beanFactory);

         //最后一步:完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // 销毁已创建的单例以避免资源悬空。
         destroyBeans();

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

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         resetCommonCaches();
      }
   }
}

分析:

  1. prepareRefresh(): 准备刷新上下文, 设置相关监听器, 以及状态开关的设置
  2. obtainFreshBeanFactory(): (1) 如果是使用AnnotationConfigApplicationContext来初始化环境: 调用的是GenericApplicationContext#refreshBeanFactory()方法,在该方法中只是对beanFactory的一些变量进行设置;

    (2) 如果是使用ClassPathXmlApplicationContext来初始化环境: 调用的是AbstractRefreshableApplicationContext#refreshBeanFactory(), 由于还没有对beanFactory进行初始化, 所以在该方法中, 完成了对beanFactory的初始化操作, 并对设置的资源位置进行扫描, 解析;  注意: 此方法是使用ClassPathXmlApplicationContext来初始化上下文是解析注册bean的重要入口

  3. prepareBeanFactory(beanFactory):  对beanFactory相关配置进行设置; 设置bean工厂的类加载器, 表达式语言处理器, 工厂后处理器, 以及需要忽略的自动装配的接口

  4. postProcessBeanFactory(beanFactory): 留给子类实现, 允许在子类中对bean工厂进行后处理

  5. invokeBeanFactoryPostProcessors(beanFactory): 激活bean工厂的后处理器 (1) 如果是使用AnnotationConfigApplicationContext来初始化环境(该方法是解析注册bean的重要入口)在该方法中执行了ConfigurationClassPostProcessor#processConfigBeanDefinitions} 方法对配置类进行解析(如果该注解bean是配置类则在这个方法里完成了包扫描操作) (2) 如果是使用ClassPathXmlApplicationContext来初始化环境, 默认情况下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息,  并没有任何Spring内部所定义的BeanFactory后处理器;  除非用户自定义了BeanFactory后处理器,  需要对BeanFactory进行修改,  那么才会执行对应后处理器里面的方法;
     注意: 注解模式下,此时BeanDefinitionMap中含有6个Spring内部处理器类(但是只有一个BeanFactoryPostProcessor类的实例-->ConfigurationClassPostProcessor), 其中通过ConfigurationClassPostProcessor类来解析配置类,完成包扫描,bean注册等操作; 然而, 在xml配置模式下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息

  6. registerBeanPostProcessors(beanFactory): 注册bean后处理处理器

  7. initMessageSource(): 为上下文初始化Message源,即不同的语言体,国际化处理

  8. initApplicationEventMulticaster(): 初始化应用消息广播,并放入"appliactionEventMulitcaster"bean中

  9. onRefresh():  留给子类来初始化其他的Bean

  10. registerListeners():  在所有注册的bean中查找listener bean,注册到消息广播器中

  11. finishBeanFactoryInitialization(beanFactory): 初始化剩下的单例(非延迟加载的,延迟加载的单例在第一次调用的时候初始化)

  12. finishRefresh(): 最后一步:完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人

  13. destroyBeans(): 销毁已创建的单例bean, 避免资源悬空

  14. cancelRefresh(ex): 重置状态开关

注: Spring容器的初始化过程主要由上面的流程实现, 这篇博客将以Xml配置进行解析, 关于注解方式会在后面解析AnnotationConfigApplicationContext时进行解析;


1. 刷新, 获取Bean工厂

_2. AbstractApplicationContext#obtainFreshBeanFactory方法实现:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   /**
    * 此处根据实现类的不同调用不同的refreshBeanFactory()方法
    *<----- 注解配置模式  ----->
    * 1. 如果是使用AnnotationConfigApplicationContext来初始化环境
    * 调用的是GenericApplicationContext#refreshBeanFactory()方法
    * {@link GenericApplicationContext#refreshBeanFactory()}
    * 在该方法中只是对beanFactory的一些变量进行设置
    *
    *<----- XML配置模式  ----->
    * 2. 如果是使用ClassPathXmlApplicationContext来初始化环境
    * 调用的是{@link AbstractRefreshableApplicationContext#refreshBeanFactory()}
    * 由于还没有对beanFactory进行初始化,所以在该方法中,完成了对beanFactory的初始化操作
    * 注意:两种方式都使用的是间接继承AbstractApplicationContext这个抽象类,并重写refreshBeanFactory()方法
    */
   refreshBeanFactory();
   /**
    * 返回已经刷新完成的bean工厂
    */
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   ...
   return beanFactory;
}

分析: 

  1. refreshBeanFactory(): 根据子类的不同实现, 执行不同的逻辑; 这里着重分析使用ClassPathXmlApplicationContext来初始化环境时, 调用AbstractRefreshableApplicationContext#refreshBeanFactory()方法; (间接继承AbstractApplicationContext这个抽象类,并重写refreshBeanFactory()方法)
  2. 返回刷新完成的bean工厂 (由AbstractRefreshableApplicationContext#getBeanFactory()方法实现)

1.1 Bean工厂的刷新以及相关配置

_1. AbstractRefreshableApplicationContext#refreshBeanFactory实现:

@Override
protected final void refreshBeanFactory() throws BeansException {
   //如果beanFactory已存在,则销毁重新创建
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      //创建DefaultListBeanFactory
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      //为了序列化指定id,如果需要的话,让这个BeanFactory从id反序列化到BeanFactory对象
      beanFactory.setSerializationId(getId());
      /**
       * 定制beanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖
       * 设置@Autowired和@Qualifer注解解析器QualifierAnnotationAutowire CandidateResolver
       */
      customizeBeanFactory(beanFactory);
      /**
       *  初始化DodumentReader,并进行XML文件读取及解析
       *1. Spring:    {@link AbstractXmlApplicationContext#loadBeanDefinitions}
       *2. SpringMvc: {@link org.springframework.web.context.support.XmlWebApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)}
       */
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   ...
}

分析: 

  1. 如果beanFactory已存在, 则销毁重新创建
  2. 创建DefaultListBeanFactory (DefaultListBeanFactory中维护注册BeanDefinition的容器,以及注册BeanName集合信息等)
  3. 定制beanFactory,设置相关属性, 包括是否允许覆盖同名称的不同定义的对象以及循环依赖, 设置@Autowired和@Qualifer注解解析器QualifierAnnotationAutowire CandidateResolver
  4. 加载BeanDefinition;  初始化DodumentReader, 并进行XML文件读取及解析

1.2 BeanDefinition的预加载

_4. AbstractXmlApplicationContext#loadBeanDefinitions实现:

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   //为指定bean创建XmlBeanDefinitionReader
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   //对beanDefinitionReader进行环境变量的设置
   beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

   //对BeanDefinition进行设置,可以覆盖
   initBeanDefinitionReader(beanDefinitionReader);
   /**
    * 加载BeanDefinition
    */
   loadBeanDefinitions(beanDefinitionReader);
}

分析: 

  1. 创建解析器XmlBeanDefinitionReader, 以及相关配置设置
  2. 加载BeanDefinition

AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)

==> AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...)

  ==> AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String)

    ==> AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String, java.util.Set<org.springframework.core.io.Resource>)

       ==> XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)

          ==> XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource)实现:

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
   //1.非空判断及日志记录
   Assert.notNull(encodedResource, "EncodedResource must not be null");
   if (logger.isInfoEnabled()) {
      logger.info("Loading XML bean definitions from " + encodedResource);
   }
   //2.通过set集合来记录当前正在加载的资源
   Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
   if (currentResources == null) {
      currentResources = new HashSet<>(4);
      this.resourcesCurrentlyBeingLoaded.set(currentResources);
   }
   //将encodedResource添加到currentResources集合中,如果添加失败,则抛出异常
   if (!currentResources.add(encodedResource)) {
      throw new BeanDefinitionStoreException(
            "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
   }
   //3.加载bean
   try {
      //通过encodedResource获取已经封装的Resource对象并再次从Resource中获取其中的inputStream
      InputStream inputStream = encodedResource.getResource().getInputStream();
      try {
         //org.xml.sax.InputSource
         InputSource inputSource = new InputSource(inputStream);
         //如果encodedResource中设置的编码不为空,则设置inputSource的编码
         if (encodedResource.getEncoding() != null) {
            inputSource.setEncoding(encodedResource.getEncoding());
         }
         /**
          * 加载bean,核心部分
          */
         return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
      }
      finally {
         //关闭输入流
         inputStream.close();
      }
   }
   catch (IOException ex) {
      throw new BeanDefinitionStoreException(
            "IOException parsing XML document from " + encodedResource.getResource(), ex);
   }
   finally {
      //加载完毕,将encodedResource从集合中移除
      currentResources.remove(encodedResource);
      if (currentResources.isEmpty()) {
         this.resourcesCurrentlyBeingLoaded.remove();
      }
   }
}

分析:

  1. 通过currentResources集合来记录当前正在加载的资源, 并将需要加载的encodedResource添加到currentResources集合中,如果添加失败,则抛出异常
  2. 获取资源输入流并封装为InputSource; 加载bean,核心部分

_2. XmlBeanDefinitionReader#doLoadBeanDefinitions实现: 

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
      throws BeanDefinitionStoreException {
   try {
      /**
       * 将配置文件解析为一个Document实例,以便下面对Bean定义进行解析
       */
      Document doc = doLoadDocument(inputSource, resource);
      /**
       * 上一个方法中当把文件装换为Document后,接下来就是对bean的提取及注册
       * 注册bean定义
       */
      return registerBeanDefinitions(doc, resource);
   }
   //异常捕获
   ...
}

分析:

  1. 将配置文件解析为一个Document实例, 以便下面对Bean定义进行解析; 在解析之前会获取资源文件的验证方式(DTD或XSD)
  2. 对bean的提取及注册bean定义

XmlBeanDefinitionReader#registerBeanDefinitions实现:

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
   //实例化BeanDefinitionDocumentReader接口
   BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
   //记录统计前BeanDefinition的加载个数
   int countBefore = getRegistry().getBeanDefinitionCount();
   /**
    * 加载及注册bean
    * {@link org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#registerBeanDefinitions(Document, XmlReaderContext)}
    */
   documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
   //记录本次加载的BeanDefinition个数
   return getRegistry().getBeanDefinitionCount() - countBefore;
}

分析:

  1. 创建Bean定义信息解析器 (DefaultBeanDefinitionDocumentReader)
  2. 加载及注册bean
  3. 返回本次注册Bean定义的数量

DefaultBeanDefinitionDocumentReader#registerBeanDefinitions实现:

@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
   this.readerContext = readerContext;
   logger.debug("Loading bean definitions");
   Element root = doc.getDocumentElement();
   /**
    * 获取节点的根节点,并将root作为参数继续BeanDefinition的注册
    */
   doRegisterBeanDefinitions(root);
}

分析: 获取配置文件的根节点, 开始注册Bean定义信息

2. 注册BeanDefinition

DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions实现:

protected void doRegisterBeanDefinitions(Element root) {
   BeanDefinitionParserDelegate parent = this.delegate;
   this.delegate = createDelegate(getReaderContext(), root, parent);
   ...
   //解析前处理,留给子类实现(设计模式:模板方法模式)
   preProcessXml(root);
   /**
    * 根据Root节点进行解析
    */
   parseBeanDefinitions(root, this.delegate);
   //解析后处理,留给子类实现(设计模式:模板方法模式)
   postProcessXml(root);
   this.delegate = parent;
}

DefaultBeanDefinitionDocumentReader#parseBeanDefinitions实现:

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
   //如果beans是默认命名空间
   if (delegate.isDefaultNamespace(root)) {
      //获取beans的所有子节点,遍历,对其子节点根据是否使用默认命名空间,使用不同的解析方法
      NodeList nl = root.getChildNodes();
      for (int i = 0; i < nl.getLength(); i++) {
         Node node = nl.item(i);
         if (node instanceof Element) {
            Element ele = (Element) node;
            //判断是否是默认命名空间
            if (delegate.isDefaultNamespace(ele)) {
               /**
                * 如果是默认命名空间(对bean的处理)
                */
               parseDefaultElement(ele, delegate);
            }
            else {
               /**
                * 如果不是默认命名空间(对bean的处理)
                */
               delegate.parseCustomElement(ele);
            }
         }
      }
   }
   //如果beans不是默认命名空间
   else {
      delegate.parseCustomElement(root);
   }
}

分析:

  1. 默认命名空间解析
  2. 自定义命名空间解析

2.1 默认命名空间解析

DefaultBeanDefinitionDocumentReader#parseDefaultElement实现:

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
   /**
    * 对import标签进行处理
    */
   if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
      importBeanDefinitionResource(ele);
   }
   /**
    * 对alias标签进行处理
    */
   else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
      processAliasRegistration(ele);
   }
   /**
    * 对bean标签进行处理
    */
   else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
      processBeanDefinition(ele, delegate);
   }
   /**
    * 对beans标签进行处理
    */
   else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
      // recurse  递归
      doRegisterBeanDefinitions(ele);
   }
}

分析:

  1. 对<import>标签进行处理
  2. 对<alias>标签进行处理
  3. 对<bean>标签进行处理(这里只分析<bean>标签的解析)
  4. 对<beans>标签进行处理

2.1.1 <bean>标签处理解析

_3. DefaultBeanDefinitionDocumentReader#processBeanDefinition实现:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
   /**
    * 1.解析ele,返回BeanDefinitionHolder类型实例bdHolder,经过这个方法后,bdHolder实例已经包含我们配置文件中配置的各种属性,例如:class,name,id,alias等
    */
   BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
   if (bdHolder != null) {
      /**
       * 2.当返回的bdHolder不为空的情况下若存在默认标签的字标签下再有自定义属性,还需要再次对自定义标签进行解析
       */
      bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
      try {
         /**
          * 3.对bdHolder进行注册
          */
         BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
      }
      catch (BeanDefinitionStoreException ex) {
         getReaderContext().error("Failed to register bean definition with name '" +
               bdHolder.getBeanName() + "'", ele, ex);
      }
      //4.发出相应事件,通知相关的监听器,这个bean已经被加载完了
      getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
   }
}

分析:

  1. 解析ele, 返回BeanDefinitionHolder类型实例bdHolder, 经过这个方法后, bdHolder实例已经包含我们配置文件中配置的各种属性, 例如:class,name,id,alias等 
  2. 当返回的bdHolder不为空的情况下若存在默认标签的字标签下再有自定义属性,还需要再次对自定义标签进行解析
  3. 对bdHolder进行注册
  4. 发出相应事件,通知相关的监听器,这个bean已经被加载完了

_3. BeanDefinitionReaderUtils#registerBeanDefinition实现:

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {
   // 根据主名称注册bean定义信息
   String beanName = definitionHolder.getBeanName();
   /**
    * GenericApplicationContext类实现了BeanDefinitionRegistry接口,
    * 并且在 GenericApplicationContext类中维护了一个DefaultListableBeanFactory beanFactory  (卧槽, 终于见到bean工厂了)
    *
    * 该步骤实际调用的是GenericApplicationContext类中的registerBeanDefinition()方法
    *{@link org.springframework.context.support.GenericApplicationContext#registerBeanDefinition(String,BeanDefinition)}
    */
   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
   // 如果该bean有别名的话, 为bean名称注册别名
   String[] aliases = definitionHolder.getAliases();
   if (aliases != null) {
      for (String alias : aliases) {
         registry.registerAlias(beanName, alias);
      }
   }
}

分析:

  1. 获取beanName, 注册Bean定义信息时以BeanName为键进行注册
  2. 注册BeanDefinition
  3. 注册别名(key=beanName, value=alias)

_2. GenericApplicationContext类定义信息:

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
   //bean工厂, 用来注册bean定义信息
   //DefaultListableBeanFactory中维护了一个
   private final DefaultListableBeanFactory beanFactory;
   . . . . . .
}

2.1.2 BeanDefinition的注册

GenericApplicationContext#registerBeanDefinition ==> DefaultListableBeanFactory#registerBeanDefinition实现:

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
   . . . 
   if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
         /**
          * 注册前的最后一次校验,这里的校验不同于之前的XML文件校验
          * 主要是对于AbstracBeanDefinition属性中的methodOverrides校验,
          * 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法不存在
          */
         ((AbstractBeanDefinition) beanDefinition).validate();
      }
      . . .
   }
   //判断该beanName是否已经注册 ,根据不同的设置记性处理; (不愧是Spring, 在我模拟的SpringIOC中我管它那么多, 直接覆盖 ,简单粗暴)
   BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
   if (existingDefinition != null) {
      //如果对应的BeanName已经注册且在配置中配置了bean不允许被覆盖,则抛出异常
      . . .
      //注册beanDefinition(将beanDefinition放入map缓存中)
      this.beanDefinitionMap.put(beanName, beanDefinition);
   }
   //处理注册未被注册的beanName的情况
   else {
      /**
        * 检查这个工厂的bean创建阶段是否已经开始,即 是否有任何bean被标记为同时创建。
        * 如果bean工厂的bean创建已经开始, 那么就不能在beanDefinitionNames集合中添加beanName; 因为创建bean时, 会迭代beanDefinitionNames集合,获取beanName,获取BeanDefinition创建bean实例
        * 一旦开始迭代, 则不允许在向该map集合中插入元素
        */
      if (hasBeanCreationStarted()) {
         //处于bean创建阶段
         //因为beanDefinitionMap是全局变量,这里肯定会存在并发访问的情况
         synchronized (this.beanDefinitionMap) {
            //注册beanDefinitionv
            this.beanDefinitionMap.put(beanName, beanDefinition);
            //创建新的集合来更新存储已注册beanName的beanDefinitionNames集合
            List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
            updatedDefinitions.addAll(this.beanDefinitionNames);
            updatedDefinitions.add(beanName);
            this.beanDefinitionNames = updatedDefinitions;
            //更新manualSingletonNames(存储单例bean)集合
            if (this.manualSingletonNames.contains(beanName)) {
               Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
               updatedSingletons.remove(beanName);
               this.manualSingletonNames = updatedSingletons;
            }
         }
      }
      //仍处于注册阶段
      else {
         //将beanName和bean的定义信息加入beanDefinitionMap集合
         this.beanDefinitionMap.put(beanName, beanDefinition);
         //bean定义名称列表,按注册顺序排列
         this.beanDefinitionNames.add(beanName);
         //手动注册的单例程序的名称列表,按注册顺序排列
         this.manualSingletonNames.remove(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }
   //如果该bean定义已经注册,并且为单例,则进行重置
   if (existingDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
   }
}

分析:

  1. 注册前的最后一次校验,这里的校验不同于之前的XML文件校验, 主要是对于AbstracBeanDefinition属性中的methodOverrides校验, 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法不存在
  2. 判断该beanName是否已经注册; 如果beanName已经注册过: 根据不同的设置进行处理(是否允许覆盖, 如果不允许,则抛出异常; 允许的话, 则进行注册)
  3. 如果beanName没有被注册过; 则开始检查这个工厂的bean创建阶段是否已经开始,即是否有任何bean被标记为同时创建。如果bean工厂的bean创建已经开始,  那么就不能在beanDefinitionNames集合中添加beanName;  因为创建bean时,  会迭代beanDefinitionNames集合,  获取beanName, 获取BeanDefinition创建bean实例;  一旦开始迭代, 则不允许在向该list集合中插入元素,  但是beanDefinitionMap集合可以,  因为beanDefinitionMap集合并没有被迭代,  而是通过beanName获取BeanDefinition信息;
  4. 如果该bean定义已经注册, 并且为单例, 则进行重置

2.2 自定义命名空间解析

BeanDefinitionParserDelegate#parseCustomElement实现:

public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
   /**spring.handler:
    *           http\://www.lic.com/schema/user=test.MyNameSpaceHandler
    *                  命名空间                NamespaceHandler
    */

   /**
    * 1.获取对应的命名空间
    */
   String namespaceUri = getNamespaceURI(ele);
   if (namespaceUri == null) {
      return null;
   }
   /**
    * 2.根据命名空间找到对应的NameSpaceHandler,用来解析XSD文件中的定义和组件定义
    * {@link org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve(java.lang.String)}
    */
   NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
   if (handler == null) {
      error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
      return null;
   }
   /**
    * 3.调用自定义的NamespaceHandler进行解析
    * {@link NamespaceHandlerSupport#parse(Element, ParserContext)}
    */
   return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}

分析:

  1. 获取对应的命名空间
  2. 根据命名空间找到对应的NameSpaceHandler, 用来解析XSD文件中的定义和组件定义
  3. 调用自定义的NamespaceHandler进行解析

2.2.1 获取名称处理器

_2. DefaultNamespaceHandlerResolver#resolve

public NamespaceHandler resolve(String namespaceUri) {
   /**
    * 获取所有已经配置的handler映射
    */
   Map<String, Object> handlerMappings = getHandlerMappings();
   //根据命名空间找到对应的信息
   Object handlerOrClassName = handlerMappings.get(namespaceUri);
   if (handlerOrClassName == null) {
      return null;
   }
   else if (handlerOrClassName instanceof NamespaceHandler) {
      //已经做过解析的情况,直接从缓存读取
      return (NamespaceHandler) handlerOrClassName;
   }
   else {
      //没有做过解析,则返回的是类路径
      String className = (String) handlerOrClassName;
      try {
         //利用反射将类路径转换为类
         Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
         ...
         //初始化类
         NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
         /**
          * 调用自定义的NamespaceHandler的初始化方法
          * SpringMvc: {@link org.springframework.web.servlet.config.MvcNamespaceHandler#init()}
          */
         namespaceHandler.init();
         //将该handler记录在缓存中,以便下次调用该handler可以直接获取,不用再次转换
         handlerMappings.put(namespaceUri, namespaceHandler);
         return namespaceHandler;
      }
      ...
   }
}

分析:

  1. 获取所有已经配置的handler映射
  2. 根据命名空间找到对应的信息
  3. 已经做过解析的情况,直接从缓存读取; 没有做过解析,则返回的是类路径,利用反射将类路径转换为类
  4. 调用自定义的NamespaceHandler的初始化方法; 初始化NamespaceHandler

示例: SpringMvc的名称空间解析器初始化方法:

@Override
public void init() {
   /**
    * 将标签名称与对应解析器关联
    *
    * 第一次尝试获取MvcNamespaceHandler时会调用该初始化方法进行初始化
    */
   registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
   registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
   registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
   registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
   registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
   registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
   registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
   registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
   registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
   registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
   registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
   registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
   registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
}

 

_3. NamespaceHandlerSupport#parse实现:

public BeanDefinition parse(Element element, ParserContext parserContext) {
   /**
    * 寻找解析器并进行解析操作,在自定义handler中并没有重写父类中parse()方法,因此此处是调用父类AbstractBeanDefinitionParser中的parse()方法
    *
    * 在parse()方法中根据标签命名空间获取不同的解析进行解析
    * 例如: 标签:<context:component-scan base-package="com.ioc.lic"/>的解析为ComponentScanBeanDefinitionParser
    * 该解析器会去解析包路径信息, 注册包路径下的所有BeanDefinition
    */
   BeanDefinitionParser parser = findParserForElement(element, parserContext);
   /**
    * 解析器1:
    * {@link AbstractBeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)}
    * 解析器2:<context:component-scan base-package="com.ioc.lic"/>
    * {@link org.springframework.context.annotation.ComponentScanBeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)}
    */
   return (parser != null ? parser.parse(element, parserContext) : null);
}

分析:

  1. 根据不同的定义标签获取对应的解析器进行解析
  2. 调用解析器中的parse()解析该标签 (这里以<context:component-scan base-package="com.ioc.lic"/>标签为例进行分析)

2.2.2 根据标签名称获取解析器

_1.NamespaceHandlerSupport#findParserForElement实现:

private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
   //获取元素名称,也就是<myname:user>中的user,若在实例中,此时localName为user
   String localName = parserContext.getDelegate().getLocalName(element);
   //根据user找到对应的解析器,也就是在 registerBeanDefinitionParser("user", new UserBeanDefinitionParser())  中注册的解析器
   BeanDefinitionParser parser = this.parsers.get(localName);
   if (parser == null) {
      parserContext.getReaderContext().fatal(
            "Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
   }
   return parser;
}

2.2.3 解析自定义标签

ComponentScanBeanDefinitionParser#parse实现:

public final BeanDefinition parse(Element element, ParserContext parserContext) {
   /**
    * 解析element
    * {@link AbstractSingleBeanDefinitionParser#parseInternal(Element, ParserContext)}
    */
   AbstractBeanDefinition definition = parseInternal(element, parserContext);
   if (definition != null && !parserContext.isNested()) {
      try {
         ...
         //将AbstractBeanDefinition装换成BeanDefinitionHolder并注册
         BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
         //注册
         registerBeanDefinition(holder, parserContext.getRegistry());
         if (shouldFireEvents()) {
            //需要通知监听器进行处理
            BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder);
            postProcessComponentDefinition(componentDefinition);
            parserContext.registerComponent(componentDefinition);
         }
      }
      ...
   }
   return definition;
}

分析: 

  1. 获取到包路径信息
  2. 配置扫描器, 扫描包路径, 注册BeanDefinition

ClassPathBeanDefinitionScanner#doScan实现:

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
   Assert.notEmpty(basePackages, "At least one base package must be specified");

   //存储扫描到的BeanDefinition信息
   Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();

   /**
    * 循环遍历包路径信息,进行解析,注册
    */
   for (String basePackage : basePackages) {
      /**
       * 扫描出该包路径下左右的候选Bean
       */
      Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
      /**
       * 对所有的候选bean进行解析
       */
      for (BeanDefinition candidate : candidates) {
         //获取Scope属性
         ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
         candidate.setScope(scopeMetadata.getScopeName());
         //根据Bean信息生成BeanName
         String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);

         //对于配置类型BeanDefinition类型和注解类型BeanDefinition类型进行区分设置
         if (candidate instanceof AbstractBeanDefinition) {
            /**
             * 如果这个类是AbstractBeanDefinition的子类
             * 则为他设置默认值,比如lazy,init destory
             */
            postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
         }
         if (candidate instanceof AnnotatedBeanDefinition) {
            /**
             * 检查并且处理常用的注解
             * 这里的处理主要是指把常用注解的值设置到AnnotatedBeanDefinition当中
             * 当前前提是这个类必须是AnnotatedBeanDefinition类型的,说白了就是加了注解的类
             */
            AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
         }

         //判断注册器中是否已经存在该BeanName
         if (checkCandidate(beanName, candidate)) {
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            beanDefinitions.add(definitionHolder);
            /**
             * 注册BeanDefinition
             */
            registerBeanDefinition(definitionHolder, this.registry);
         }
      }
   }
   return beanDefinitions;
}

3. Bean工厂配置的设置

_3. AbstractApplicationContext#prepareBeanFactory实现:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // 告诉内部bean工厂使用上下文的类加载器等等。
   beanFactory.setBeanClassLoader(getClassLoader());
   //设置beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持
   //默认可以使用#{bean.xxx}的形式来调用相关属性值
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   //为beanfactory增加了一个默认的属性编辑器,这个主要是对bean的属性等设置管理的一个工具
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // 给beanFactory添加后置处理器
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

   //设置了几个忽略自动装配的接口()
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   // BeanFactory interface not registered as resolvable type in a plain factory.
   // MessageSource registered (and found for autowiring) as a bean.\
   //设置了几个自动装配的特殊规则
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // Register early post-processor for detecting inner beans as ApplicationListeners.
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));


   //增加对AspectJ的支持
   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   //添加默认系统环境bean
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

4. 激活Bean工厂后处理器

_5. AbstractApplicationContext#invokeBeanFactoryPostProcessors实现:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   /**
    * getBeanFactoryPostProcessors()方法:
    * 获取通过{@link AbstractApplicationContext#addBeanFactoryPostProcessor(BeanFactoryPostProcessor)}
    * 方法添加的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的beanFactory处理器类
    *
    * 注意: 如果是自定义的添加@Component注解的,此处是获取不到的, 后面Spring会自动去扫描
    *       如果此处存在自定义的类,则会在ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法之前执行
    */
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
   // 检测LoadTimeWeaver并准备编织(如果在此期间发现)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

分析:

  1. getBeanFactoryPostProcessors()方法: 获取通过AbstractApplicationContext#addBeanFactoryPostProcessor方法添加的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的beanFactory处理器类
  2. 激活Bean工厂后处理器; 通常情况下这里主要激活的是Spring内部的工厂后处理器

注意: 如果是自定义的添加@Component注解的,此处是获取不到的, 后面Spring会自动去扫描; 如果此处存在自定义的类,则会在ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法之前执行

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors实现:

/**
 * 1. 执行自定义的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
 *
 * 2. 执行Spring内部的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
 *  {@link PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors(Collection, BeanDefinitionRegistry)}
 *
 * 3. 执行自定义的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口时重写的postProcessBeanFactory()方法
 *      和Spring内部的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanFactory()方法
 *
 * 4. 执行Spring内部实现BeanFactoryPostProcessor接口的处理器中的postProcessBeanFactory()方法
 * {@link PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(Collection, ConfigurableListableBeanFactory)}
 *
 *
 */
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
   Set<String> processedBeans = new HashSet<>();

   if (beanFactory instanceof BeanDefinitionRegistry) {
      //注意: 前提条件是改注册器是实现了BeanDefinitionRegistry接口的
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

      /**
       *  1. 将自定义的实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的类区分保存在不同的集合中
       *     在区分过程中执行自定义实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
       */

      /**
       * 注意: BeanDefinitionRegistryPostProcessor接口 继承了 BeanFactoryPostProcessor接口
       * 之所以要将所有的后处理器区分开, 是因为实现BeanDefinitionRegistryPostProcessor接口的要执行两个方法
       * {@link BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)}
       * 和{@link BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)}这两个方法
       * 而实现BeanFactoryPostProcessor接口的只需要执行{@link BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)}
       * 这个方法即可
       */
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

      /**
       * 遍历bean工厂后处理器集合,将不同的处理器添加分别添加到regularPostProcessors和registryProcessors集合中
       * beanFactoryPostProcessors集合中存储的是用户自定义的后处理器类
       * 有两种方式自定义:
       *        (1). 实现BeanDefinitionRegistryPostProcessor接口重写postProcessBeanDefinitionRegistry()方法和postProcessBeanFactory()方法, 还需要加@Component注解
       *        (2). 实现BeanFactoryPostProcessor接口重写postProcessBeanFactory()方法, 还需要加@Component注解
       */
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =  (BeanDefinitionRegistryPostProcessor) postProcessor;
            //执行自定义实现BeanDefinitionRegistryPostProcessor接口的类中的postProcessBeanDefinitionRegistry()方法
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else {
            regularPostProcessors.add(postProcessor);
         }
      }


      /**
       *  2. 将Spring内部的实现BeanDefinitionRegistryPostProcessor接口的根据优先级顺序执行 处理器类中重写该接口的postProcessBeanDefinitionRegistry()方法
       *  (实现PriorityOrdered接口的先执行,实现ordered接口的后执行,两者都没有实现的,最后执行)
       */

      /**
       * 将实现PriorityOrdered,Ordered等接口的BeanDefinitionRegistryPostProcessors分开按优先级执行
       * 这个currentRegistryProcessors 存储的是spring内部自己实现了BeanDefinitionRegistryPostProcessor接口的对象
       */
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      /**
       * 2.1 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessor
       *     根据BeanDefinitionRegistryPostProcessor.class获取所有实现BeanDefinitionRegistryPostProcessor接口的beanName;
       *     getBeanNamesForType()
       *    {@link DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class, boolean, boolean)}
       */
      String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      /**
       *  这个地方可以得到一个BeanFactoryPostProcessor(org.springframework.context.annotation.internalConfigurationAnnotationProcessor ->内部配置注解处理器),
       *  因为是spring默认在最开始自己注册的,在下面的方法中注册的
       * {@link AnnotationConfigUtils#registerAnnotationConfigProcessors()}
       *
       *     为什么要在最开始注册这个呢?
       * 因为spring的工厂需要许解析去扫描等等功能,这些功能都是需要在spring工厂初始化完成之前执行
       * 要么在工厂最开始的时候、要么在工厂初始化之中,反正不能再之后; 因为如果在之后就没有意义,因为那个时候已经需要使用工厂了
       * 所以这里spring在一开始就注册了一个BeanFactoryPostProcessor,用来插手springfactory的实例化过程
       * 在这个地方断点可以知道这个类叫做ConfigurationClassPostProcessor
       * (ConfigurationClassPostProcessor类的beanName为"org.springframework.context.annotation.internalConfigurationAnnotationProcessor")
       *
       * ConfigurationClassPostProcessor那么这个类能干嘛呢?    ----> 很重要
       * Spring使用ConfigurationClassPostProcessor完成对注解的扫描
       * (1) ConfigurationClassPostProcessor调用postProcessBeanDefinitionRegistry()方法
       *    {@link PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors(Collection, BeanDefinitionRegistry)}
       * (2) 在步骤四中ConfigurationClassPostProcessor调用postProcessBeanFactory()方法
       *    {@link PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(Collection, BeanDefinitionRegistry)}
       *
       */
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            //即将执行的BeanDefinitionRegistryPostProcessor类
            processedBeans.add(ppName);
         }
      }
      //根据PriorityOrdered接口设置的不同优先级进行排序
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      //将Spring内部实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor类实添加到registryProcessors结合中,便于后面一块执行postProcessBeanFactory()方法
      // 在下面的执行中只执行Spring内部的,自定义的在上面区分两种类时已经执行过了
      registryProcessors.addAll(currentRegistryProcessors);
      /**
       * 循环遍历currentRegistryProcessors,.执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法
       * {@link BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)}
       * 该方法时BeanDefinitionRegistryPostProcessor接口继承BeanFactoryPostProcessor接口后增加的方法
       */
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      //currentRegistryProcessors集合中的类遍历执行完postProcessBeanDefinitionRegistry()方法后,清空该集合,以便后面进行重复使用
      currentRegistryProcessors.clear();


      /**
       * 2.2  接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessor
       */
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         // !processedBeans.contains(ppName) 如果processedBeans集合中已存在该beanName,那么说明已经执行过了,不需要再次执行
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            //把符合条件的BeanDefinition从从工厂中获取出来, 存储到currentRegistryProcessors集合中
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            //即将执行的BeanDefinitionRegistryPostProcessor类
            processedBeans.add(ppName);
         }
      }
      //根据Ordered接口设置的不同优先级进行排序
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      //将Spring内部实现Ordered接口的BeanDefinitionRegistryPostProcessor类实添加到registryProcessors结合中,便于后面一块执行postProcessBeanFactory()方法
      //在下面的执行中只执行Spring内部的,自定义的在上面区分两种类时已经执行过了
      registryProcessors.addAll(currentRegistryProcessors);
      //同上, 优先执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor, 然后再执行实现Ordered接口的
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      /**
       * 2.3  最后,执行其他没有实现PriorityOrdered接口和ordered接口的注册器后处理器类
       */
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName)) {
               //把符合条件的BeanDefinition从从工厂中获取出来, 存储到currentRegistryProcessors集合中
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         //将Spring内部实现Ordered接口的BeanDefinitionRegistryPostProcessor类实添加到registryProcessors结合中,便于后面一块执行postProcessBeanFactory()方法
         registryProcessors.addAll(currentRegistryProcessors);
         //同上, 该步骤执行没有实现PriorityOrdered接口和Ordered接口的处理器类的BeanDefinitionRegistryPostProcessor()方法
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }

      /**
       * 3. 执行所有处理器类(实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的)的BeanFactoryPostProcessor方法
       *    因为BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcessor接口,所以实现BeanDefinitionRegistryPostProcessor接口的处理器类也需要
       *    重写BeanFactoryPostProcessor接口中的BeanFactoryPostProcessor方法
       *
       *    注意: registryProcessors中存储的是Spring内部和自定义实现BeanDefinitionRegistryPostProcessor接口的处理器类
       *          regularPostProcessors中存储的是自定义实现BeanFactoryPostProcessor接口的处理器类
       */
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   // 如果该注册器是没有实现BeanDefinitionRegistry接口
   else {
      // 调用用上下文实例注册的工厂处理器
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }


   /**
    * 4. 执行Spring内部实现BeanFactoryPostProcessor接口的处理器中的postProcessBeanFactory()方法
    * 根据BeanFactoryPostProcessor类型获取到所有Spring内部实现BeanFactoryPostProcessor接口的处理器类的beanName
    * {@link DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class, boolean, boolean)}
    */
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   //初始化存储实现PriorityOrdered接口的处理器的集合
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   //初始化存储实现Ordered接口的BeanName的集合,后面还需要再次遍历该集合, 获取BeanDefinition存储到orderedPostProcessors集合中
   List<String> orderedPostProcessorNames = new ArrayList<>();
   //初始化存储没有实现PriorityOrdered接口和Ordered接口的BeanName的集合,后面还需要再次遍历该集合, 获取BeanDefinition存储到nonOrderedPostProcessors集合中
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();

   //遍历postProcessorNames集合中所有的postProcessorName,从bean工厂中获取到相关的bean定义,存储在不同的集合中
   for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            //注意此处存储的是beanName;
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   /**
    *  4.1 执行实现PriorityOrdered接口的BeanFactoryPostProcessors处理器类
    */
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   /**
    * 4.2  遍历orderedPostProcessorNames集合, 获取BeanDefinition存储到orderedPostProcessors集合中
    *      然后执行实现Ordered接口的BeanFactoryPostProcessors处理器类
    */
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   /**
    * 4.3  遍历nonOrderedPostProcessorNames集合, 获取BeanDefinition存储到nonOrderedPostProcessors集合中
    */
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

   //清除缓存的合并bean定义,因为后处理器可能有修改原始元数据,例如替换值中的占位符…
   beanFactory.clearMetadataCache();

}

分析: 这个方法很复杂, 也很重要; 大体上可以分为以下四个部分:

  1. 执行自定义实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法
  2. 执行Spring内部实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanDefinitionRegistry()方法PostProcessorRegistrationDelegate# invokeBeanDefinitionRegistryPostProcessors
  3. 执行自定义实现BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口时重写的postProcessBeanFactory()方法和Spring内部的实现BeanDefinitionRegistryPostProcessor接口时重写的postProcessBeanFactory()方法
  4.  执行Spring内部实现BeanFactoryPostProcessor接口的处理器中的postProcessBeanFactory()方法PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

注:  这里仅介绍大体逻辑, 详细解析内容已在代码中标注;  对于使用ClassPathXmlApplicationContext初始化IOC容器,  一般情况下此处并没有执行任务Bean工厂后处理器, 并没有太大作用; 但是如果使用注解方式AnnotationConfigApplicationContext来初始化应用环境, 这里面将会激活一个bean工厂后处理器ConfigurationClassPostProcessor; Spring使用ConfigurationClassPostProcessor完成对注解的扫描, 相关内容在后面播客中会进行详细解析

 

5. 注册bean后处理处理器

_6. AbstractApplicationContext#registerBeanPostProcessors

        ==> PostProcessorRegistrationDelegate#registerBeanPostProcessors实现:

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
   /**
    * BeanPostProcessorChecker是一个普通的信息打印,但是会出现一些请况:
    * 当Spring的配置中的后处理器还没有被注册就已经开始了bean的初始化时,便会打印出BeanPostProcessorChecker中设定的信息
    */
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   //使用priorityOrdered保证顺序
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   //使用Ordered保证顺序
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   //将bean处理器分类存储
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   //第一步,注册所有实现了PriorityOrdered接口的BeanPostProcessors
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   /**
    * {@link org.springframework.beans.factory.support.AbstractBeanFactory#addBeanPostProcessor(BeanPostProcessor)}
    */
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   //第二步,注册所有实现Ordered的BeanPostProcessors
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   //第三步,注册所有无序的BeanPostProcessor
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   //第四步,注册所有MergedBeanDefinitionPostProcessors类型的BeanPostProcessor,并非重复注册
   //在beanFactory.addBeanPostProcessor中会先移除已经存在的BeanPostProcessor
   sortPostProcessors(internalPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   //添加ApplicationListener探测器
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

分析: 先按照BeanPostProcessor.class从bean工厂中获取所有的Bean后处理器名称, 按照优先级对Bean后处理器进行注册

6. 初始化非延迟加载的的单例Bean (延迟加载的单例将在第一次调用的时候初始化)

_11. AbstractApplicationContext#finishBeanFactoryInitialization实现:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }

   // Register a default embedded value resolver if no bean post-processor
   // (such as a PropertyPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   beanFactory.freezeConfiguration();

   /**
    * 实例化所有的单例对象
    * {@link org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons()}
    */
   beanFactory.preInstantiateSingletons();
}

DefaultListableBeanFactory#preInstantiateSingletons实现:

@Override
public void preInstantiateSingletons() throws BeansException {
   if (logger.isDebugEnabled()) {
      logger.debug("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   /**
    * 获取所有注册的BeanName, 后面将遍历这个集合进行实例化;注意: 这里是对beanDefinitionNames集合进行拷贝
    */
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   /**
    * 触发所有非惰性单例bean的初始化...
    */
   for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         /**
          * 如果是工厂bean
          */
         if (isFactoryBean(beanName)) {
            //在beanName前加"&"前缀, 获取到FactoryBean (如果直接通过BeanName获取的则是getObject()方法返回的bean)
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            //判断该bean对象是否是FactoryBean
            if (bean instanceof FactoryBean) {
               //如果是的话则进行强转
               final FactoryBean<?> factory = (FactoryBean<?>) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                              ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               //只有isEagerInit值为true,才会在此时对FactoryBean进行初始化
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         /**
          * 如果是普通bean
          */
         else {
            getBean(beanName);
         }
      }
   }

   /**
    * 触发所有适用bean的初始化后回调...
    * 如果目标Bean实现了SmartInitializingSingleton接口并重写了afterSingletonsInstantiated()方法,
    * 这里将会执行该方法
    */
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            /**
             * 执行afterSingletonsInstantiated()方法
             */
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

 分析:

  1. 获取所有注册的BeanName, 后面将遍历这个集合进行实例化;注意: 这里是对beanDefinitionNames集合进行拷贝
  2. 触发所有非惰性单例bean的初始化, 对工厂bean和普通bean区分处理
  3. 触发所有适用bean的初始化后的回调方法afterSingletonsInstantiated()

AbstractBeanFactory#getBean   ==> AbstractBeanFactory#doGetBean

注: 关于Bean的初始化在后面播客会专门讲解, 这里不再分析了

7. 应用上下文刷新结束, 进行事件广播

_12. AbstractApplicationContext#finishRefresh实现:

protected void finishRefresh() {
   //清除上下文级别的资源缓存(例如来自扫描的ASM元数据)
   clearResourceCaches();

   //为此上下文初始化生命周期处理器
   initLifecycleProcessor();

   //首先将刷新传播到生命周期处理器
   getLifecycleProcessor().onRefresh();

   /**
    * 发布结束事件(事件对象:ContextRefreshedEvent)
    */
   publishEvent(new ContextRefreshedEvent(this));

   // Participate in LiveBeansView MBean, if active.
   LiveBeansView.registerApplicationContext(this);
}

分析:  刷新结束后一些资源的清理以及生命周期的设置, 以及发布结束事件, 通知监听者Spring容器以及初始化完成, 观察者可以进行相关操作

至此, ClassPathXmlApplicationContext方式初始化容器解析完成;

 

相关文章:

     Spring源码解析一 (IOC容器初始化深度解析)

     Spring源码解析二 (IOC容器初始化方式一:XmlBeanFactory)

     Spring源码解析三 (IOC容器初始化方式二:ClassPathXmlApplicationContext)

     Spring源码解析四 (IOC容器初始化方式三: AnnotationConfigApplicationContext[包路径配置方式])

     Spring源码解析五 (IOC容器初始化方式四: AnnotationConfigApplicationContext[Java配置类方式])

     Spring源码解析六 (Bean的初始化)

     Spring源码解析七 (AOP深度解析)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值