01.spring全家桶之深入refresh()

124 阅读25分钟

refresh()AbstractApplicationContext 中的一个方法,负责初始化 ApplicationContext 容器,容器必须调用 refresh() 才能正常工作。它的内部主要会调用 12 个方法,我们把它们称为 refresh 的 12 个步骤:

refresh() 执行流程图见:www.processon.com/view/link/5…


public abstract class AbstractApplicationContext extends DefaultResourceLoader
      implements ConfigurableApplicationContext {

    @Override
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
          //1:准备刷新上下文环境
          prepareRefresh();

          //2:获取告诉子类初始化Bean工厂
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

          //3:对bean工厂进行填充属性
          /**
           * 主要有:
           * 添加了2个beanpostprocessor
           * 注册了3个单例对象:environment systemProperties systemEnvironment
           */
          prepareBeanFactory(beanFactory);

          try {
             // 4.留给子类去重写该方法,允许子类修改beanFactory
             postProcessBeanFactory(beanFactory);

             // 5.调用我们的bean工厂的后置处理器.
             invokeBeanFactoryPostProcessors(beanFactory);

             // 6.调用我们bean的后置处理器
             registerBeanPostProcessors(beanFactory);

             // 7.初始化国际化资源处理器.
             initMessageSource();

             // 8.创建事件多播器
             initApplicationEventMulticaster();

             // 9.这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomat的.
             onRefresh();

             // 10.把我们的事件监听器注册到多播器上
             registerListeners();

             // 11.实例化我们剩余的单实例bean.
             finishBeanFactoryInitialization(beanFactory);

             // 12.最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
             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. prepareRefresh();

准备刷新上下文环境

protected void prepareRefresh() {
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   this.active.set(true);
   /**
    *
    * 扩展点:供子类重写,使用如下
    * public class MyApplicationContext extends AnnotationConfigApplicationContext {
    *        @Override
    *        protected void initPropertySources() {
    *
    *        }
    * }
    *
    * AnnotationConfigApplicationContext ctx = new MyApplicationContext();
    *
    * 相传该方法在网上很多人说该方法没有用,因为这个方法是留个子类实现的,由于是对spring源码的核心
    * 设计理念没有弄清楚,正式由于spring提供了大量的可扩展的接口提供给我们自己来实现
    * 比如我们自己写一个类重写了initPropertySources方法,在该方法中设置了一个环境变量的值为A
    * 启动的时候,我的环境变量中没有该值就会启动抛出异常
    */
   initPropertySources();

   /**
    * 用来校验我们容器启动必须依赖的环境变量的值,可以忽略
    */
   getEnvironment().validateRequiredProperties();

   /**
    * 创建一个早期事件监听器对象
    */
   if (this.earlyApplicationListeners == null) {
      this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
   } else {
      // Reset local application listeners to pre-refresh state.
      this.applicationListeners.clear();
      this.applicationListeners.addAll(this.earlyApplicationListeners);
   }

   /**
    * 创建一个容器用于保存早期待发布的事件集合
    * 什么是早期事件了?
    * 就是我们的事件监听器listener还没有注册到多播器上的时候都称为早期事件
    */
   this.earlyApplicationEvents = new LinkedHashSet<>();
}

2. obtainFreshBeanFactory();

获取告诉子类始化Bean工厂

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   /**
    * 普通的spring环境的时候,那么这这里bean工厂已经被创建,所以调用GenericApplicationContext#refreshBeanFactory()刷新工厂。
    * 而springmvc的环境的时候,bean工厂还没有创建,需要通过refreshBeanFactory()创建
    */
   refreshBeanFactory();
   //返回我们的bean工厂
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   return beanFactory;
}

protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

@Override
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

AbstractRefreshableApplicationContext

@Override
protected final void refreshBeanFactory() throws BeansException {
   //若已经存在了 就信息销毁等操作
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      /**
       * 为我们的Spring应用上下文对象创建我们的beanFactory,默认是DefaultListableBeanFactory
       */
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId()); //为容器设置一个序列化ID

      customizeBeanFactory(beanFactory);  //扩展点:允许子类重写该方法
      
      //加载我们的bean定义(最最最主要的作用就是保存我们的传递进去的配置类)
      loadBeanDefinitions(beanFactory);
      
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   } catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

protected DefaultListableBeanFactory createBeanFactory() {
   return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)  throws BeansException, IOException;

2.1 loadBeanDefinitions(beanFactory);

3. prepareBeanFactory(beanFactory);

对bean工厂进行填充属性,主要有:添加了2个beanpostprocessor;注册了3个单例对象:environment systemProperties systemEnvironment等

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   //设置bean工厂的类加载器为当前application应用的加载器
   beanFactory.setBeanClassLoader(getClassLoader());
   //为bean工厂设置我们标准的SPEL表达式解析器对象StandardBeanExpressionResolver
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   //为我们的bean工厂设置了一个propertyEditor 属性资源编辑器对象(用于后面的给bean对象赋值使用)
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   //注册了一个完整的ApplicationContextAwareProcessor 后置处理器用来处理ApplicationContextAware接口的回调方法
   // Bean后置处理器BeanPostProcessor
   // postProcessBeforeInitialization 主要是在回调该方法的时候设置6大Aware
   // postProcessAfterInitialization  该方法中没啥
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   /**
    * 当 Spring 将 ApplicationContextAwareProcessor 注册后,那么在 invokeAwareInterfaces 方法中间接调用的 Aware 类已经不是普通的 bean 了 ,
    * 如 ResourceLoaderAware、 ApplicationEventPublisher 等,那么当然需要在 Spring 做 bean 的依赖注入的时候忽略它们。
    * 而 ignoreDependencyInterface 的作用正是在此
    */
   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.class 的解析依赖后,
    * 当 bean的属性注入的时候, 一旦检测到属性为 BeanFactory 类型便会将 beanFactory 的实例注入进去。
    *  结合@Autowired使用
    */
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   //注册了一个事件监听器探测器后置处理器接口ApplicationListenerDetector:
   // 该BeanPostProcessor检测那些实现了接口ApplicationListener的bean,
   // 在它们创建时初始化之后,将它们添加到应用上下文的事件多播器上;
   // 并在这些ApplicationListener bean销毁之前,将它们从应用上下文的事件多播器上移除
   // Bean后置处理器BeanPostProcessor
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // 处理aspectj的
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { // loadTimeWeaver
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   //注册了bean工厂的内部的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. postProcessBeanFactory(beanFactory);

默认空实现,留给子类去实现该接口,允许子类修改beanFactory

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

该方法一般由子类AbstractRefreshableWebApplicationContext重写,具体实现如下:

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // 如果class实现ServletContextAware、ServletConfigAware,ServletContextAwareProcessor负责注入context和config
   beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
   beanFactory.ignoreDependencyInterface(ServletContextAware.class);
   beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
   // 注册servlet环境相关的scope
   WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
   // 向spring中注册跟servlet相关的单例bean
   WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

5. invokeBeanFactoryPostProcessors(beanFactory);

调用我们的bean工厂的后置处理器

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   //传入bean工厂和获取applicationContext中的bean工厂后置处理器(但是由于没有任何实例化过程,所以传递进来的为空)
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

5.1 invokeBeanFactoryPostProcessors

执行流程如下

  1. 获取getBeanFactoryPostProcessors()中实现了BeanDefinitionRegistryPostProcessor这1个接口的所有PostProcessor,回调postProcessBeanDefinitionRegistry()(这一步暂时可以忽略)

  2. 获取spring容器中实现了BeanDefinitionRegistryPostProcessorPriorityOrdered这2个接口的beanName,主动getBean(),回调postProcessBeanDefinitionRegistry()(这一步中有一个很重要的类ConfigurationClassPostProcessor会被回调此方法,用于进行bean定义的加载 比如我们的包扫描,处理@Import等等)

  3. 获取spring容器中实现了BeanDefinitionRegistryPostProcessorOrdered这2个接口的beanName,主动getBean(),回调postProcessBeanDefinitionRegistry()(这一步暂时可以忽略)

  4. 获取spring容器中实现了BeanDefinitionRegistryPostProcessor这1个接口的beanName,主动getBean(),回调postProcessBeanDefinitionRegistry()(这一步暂时可以忽略)

  5. 获取上面中所有的BeanDefinitionRegistryPostProcessor,回调BeanFactoryPostProcessor#postProcessBeanFactory()

  6. 获取getBeanFactoryPostProcessors()中实现了BeanFactoryPostProcessor这1个接口的所有PostProcessor,回调postProcessBeanFactory()

  7. 获取spring容器中实现了BeanFactoryPostProcessorPriorityOrdered这2个接口的beanName,主动getBean(),回调postProcessBeanFactory()

  8. 获取spring容器中实现了BeanFactoryPostProcessor和Ordered这2个接口的beanName,主动getBean(),回调postProcessBeanFactory()

  9. 获取spring容器中实现了BeanFactoryPostProcessor这1个接口的beanName,主动getBean(),回调postProcessBeanFactory()

可以参考下图: image.png 源码如下:

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
   /**
    * 处理beanfactory后置处理器
    *        回调BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
    *
    * 找到BeanDefinition中实现了
    * BeanDefinitionRegistryPostProcessor
    *    PriorityOrdered
    * 回调postProcessBeanDefinitionRegistry方法
    *
    * BeanDefinitionRegistryPostProcessor
    *        Ordered
    * 回调postProcessBeanDefinitionRegistry方法
    *
    * BeanDefinitionRegistryPostProcessor
    * 回调postProcessBeanDefinitionRegistry方法
    *
    * 回调postProcessBeanFactory方法
    */
   
   //第一步:首先调用BeanDefinitionRegistryPostProcessor的后置处理器
   Set<String> processedBeans = new HashSet<>();
   
   if (beanFactory instanceof BeanDefinitionRegistry) { // 默认true
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      //保存BeanFactoryPostProcessor类型的后置
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      //保存BeanDefinitionRegistryPostProcessor类型的后置处理器
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
      
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            
            registryProcessors.add(registryProcessor);
         } else { //若没有实现BeanDefinitionRegistryPostProcessor 接口,那么他就是BeanFactoryPostProcessor
            regularPostProcessors.add(postProcessor);
         }
      }
      
      //定义一个集合用户保存当前准备创建的BeanDefinitionRegistryPostProcessor
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
      
      String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 目前就一个:ConfigurationClassPostProcessor
            //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            //同时也加入到processedBeans集合中去
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      /**
       * 在这里典型的BeanDefinitionRegistryPostProcessor就是ConfigurationClassPostProcessor
       * 用于进行bean定义的加载 比如我们的包扫描,@import  等等。。。。。。。。。
       */
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();
      
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         //表示没有被处理过,且实现了Ordered接口的
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();
      
      //调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor
      //定义一个重复处理的开关变量 默认值为true
      boolean reiterate = true;
      //第一次就可以进来
      while (reiterate) {
         //进入循环马上把开关变量给改为fasle
         reiterate = false;
         //去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         //循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
         for (String ppName : postProcessorNames) {
            //没有被处理过的
            if (!processedBeans.contains(ppName)) {
               //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
               // 有可能在此getBean的过程中产生了新的bean刚刚被注入到beanFactory中,而这些bean也实现了BeanDefinitionRegistryPostProcessor,为了他们被探测到
               // 所以while循环调用
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }
      
      //调用实现了BeanDefinitionRegistryPostProcessor的接口 他是他也同时实现了BeanFactoryPostProcessor的方法
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      //调用BeanFactoryPostProcessor成品的不是通过getBean的
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   } else { //若当前的beanFacotory没有实现了BeanDefinitionRegistry 直接电泳
      //直接调用beanFacotoryPostProcessor接口的方法进行后置处理
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }
   
   //获取容器中所有的 BeanFactoryPostProcessor
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
   
   //保存BeanFactoryPostProcessor类型实现了priorityOrdered
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   //保存BeanFactoryPostProcessor类型实现了Ordered接口的
   List<String> orderedPostProcessorNames = new ArrayList<>();
   //保存BeanFactoryPostProcessor没有实现任何优先级接口的
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      //processedBeans包含的话,表示在上面处理BeanDefinitionRegistryPostProcessor的时候处理过了
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
      //判断是否实现了PriorityOrdered
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      //判断是否实现了Ordered
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      //没有实现任何的优先级接口的
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }
   
   // 先调用BeanFactoryPostProcessor实现了 PriorityOrdered接口的
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
   
   //再调用BeanFactoryPostProcessor实现了 Ordered.
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
   
   //调用没有实现任何方法接口的
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
   
   // Clear cached merged bean definitions since the post-processors might have
   // modified the original metadata, e.g. replacing placeholders in values...
   beanFactory.clearMetadataCache();
}

5.2 LoadTimeWeaverAwareProcessor

检测LoadTimeWeaver并准备编织(如果同时发现)

if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
   beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
   beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}

一般情况下该if可以直接忽略的,默认都是false。当然我们可以使用@EnableLoadTimeWeaving注解启用运行时织入功能,利用aspectj功能增强。它会向spring中默认注册一个DefaultContextLoadTimeWeaver的beanDefinition,那么会导致该if为true。

如果if为true,它会向spring factory注册一个特殊的BeanPostProcessor也就是 LoadTimeWeaverAwareProcessor,该processor功能很简单,就是如果发现有bean实现了LoadTimeWeaverAware接口,就调用setLoadTimeWeaver()方法给当前bean绑定一个LoadTimeWeaver对象,具体可以参考@EnableLoadTimeWeaving

6. registerBeanPostProcessors(beanFactory);

向spring factory中注册BeanPostProcessor。spring中有各式各样的bean,他们可能实现了BeanPostProcessor接口,但是此时他们的bean还没有生成,这里就是提前生成这些特殊的bean,那我们就可以在其他普通bean的生命周期中让他们发挥作用了

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

遍历spring中所有实现了BeanPostProcessor接口的beanName,依次按照优先级从高到低顺序去实例化下面这些bean:

  1. 实现了BeanFactoryPostProcessorPriorityOrdered这2个接口的
  2. 实现了BeanFactoryPostProcessorOrdered这2个接口的
  3. 只实现了BeanFactoryPostProcessor这1个接口的
  4. 把他们都注册到spring factory中,见下:
private static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
   for (BeanPostProcessor postProcessor : postProcessors) {
      beanFactory.addBeanPostProcessor(postProcessor);
   }
}
  1. 向spring factory单独在注册一个ApplicationListenerDetector(本质上也是一个BeanFactoryPostProcessor),它用来负责在探测spring中那些实现了ApplicationListener接口的特殊bean,把他们注册到事件多播器 applicationEventMulticaster上,那么这些bean就可以接收到ApplicationEvent事件了

7. initMessageSource();

初始化国际化资源处理器,默认是DelegatingMessageSource

protected void initMessageSource() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   if (beanFactory.containsLocalBean("messageSource")) {
      this.messageSource = beanFactory.getBean("messageSource", MessageSource.class);
      if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
         HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
         if (hms.getParentMessageSource() == null) {
            hms.setParentMessageSource(getInternalParentMessageSource());
         }
      }
   } else {
      // Use empty MessageSource to be able to accept getMessage calls.
      DelegatingMessageSource dms = new DelegatingMessageSource();
      dms.setParentMessageSource(getInternalParentMessageSource());
      this.messageSource = dms;
      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
   }
}

8. initApplicationEventMulticaster();

初始化事件多播器,默认是SimpleApplicationEventMulticaster,负责广播各种ApplicationEvent事件

protected void initApplicationEventMulticaster() {
   //获取我们的bean工厂对象
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   //判断容器中是没有有我们的applicationEventMulticaster 应用多播器组件
   if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
      //直接显示的调用我们的getBean获取出来赋值给我们的applicationContext对象
      this.applicationEventMulticaster =  beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
   }
   //容器中没有的话
   else {
      //spring ioc显示的new 一个SimpleApplicationEventMulticaster对象保存在applicatoinContext对象中
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
   }
}

9. onRefresh();

默认空实现,这个方法同样也是留给子类实现的。springboot就是从这个方法进行启动tomcat的。

protected void onRefresh() throws BeansException {
   // For subclasses: do nothing by default.
}

10. registerListeners();

把我们的事件监听器注册到多播器上

protected void registerListeners() {
   //获取容器中所有的监听器对象(成品对象)
   for (ApplicationListener<?> listener : getApplicationListeners()) {
      //把监听器挨个的注册到我们的多播器上去
      getApplicationEventMulticaster().addApplicationListener(listener);
   }

   //获取bean定义中的监听器对象
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   //把监听器的名称注册到我们的多播器上
   for (String listenerBeanName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }

   //在这里获取我们的早期事件
   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (earlyEventsToProcess != null) {
      //通过多播器进行播发早期事件
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}

11. finishBeanFactoryInitialization(beanFactory);

完成此上下文的bean工厂的初始化,初始化所有剩余的singleton bean。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // 为我们的bean工厂创建类型转化器  Convert
   /*
    * public class String2DateConversionService implements Converter<String,Date> {

       public Date convert(String source) {
          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
          try {
            return sdf.parse(source);
          } catch (ParseException e) {
            return null;
          }
       }
    }

    @Bean 
    public ConversionServiceFactoryBean conversionService() {
      ConversionServiceFactoryBean factoryBean = new ConversionServiceFactoryBean();
      Set<Converter> converterSet = new HashSet<Converter>();
      converterSet.add(new String2DateConversionService());
      factoryBean.setConverters(converterSet);
      return factoryBean;
    }
    
    ConversionServiceFactoryBean conversionServiceFactoryBean = (ConversionServiceFactoryBean) ctx.getBean(ConversionServiceFactoryBean.class);
    conversionServiceFactoryBean.getObject().convert("2019-06-03 12:00:00", Date.class)
    */
   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));
   }

   /*
    public class MainConfig implements EmbeddedValueResolverAware{
      public void setEmbeddedValueResolver(StringValueResolver resolver) {
         this.jdbcUrl = resolver.resolveStringValue("${ds.jdbcUrl}");
         this.classDriver = resolver.resolveStringValue("${ds.classDriver}");
      }
    }
    */
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // 处理关于aspectj
   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);

   //冻结所有的 bean 定义 , 说明注册的 bean 定义将不被修改或任何进一步的处理
   beanFactory.freezeConfiguration();

   //实例化剩余的单实例bean
   beanFactory.preInstantiateSingletons();
}

11.1 ConversionService

为我们的spring factory设置一个类型转换器ConversionService。感兴趣的可以参考我写的关于ConversionService的掘金文章

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));
}

11.2 StringValueResolver

为我们的spring factory添加一个内置的StringValueResolver,用于解析占位符${}

if (!beanFactory.hasEmbeddedValueResolver()) {
   beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}

11.3 LoadTimeWeaverAware

如果发现spring中存在bean实现了LoadTimeWeaverAware接口,那就在这里先生成bean。

那这个接口是用来干什么的呢?顾名思义:加载时织入。就是在一个class被某个classloader加载时在这个class本身功能的基础上利用aspectj做一些增强,类似aop。一般情况下用不到。感兴趣的可以看一下我写的关于@EnableLoadTimeWeaving的掘金文章

String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
   getBean(weaverAwareName);
}

11.4 beanFactory.preInstantiateSingletons();

实例化剩余的单实例bean,最后回调SmartInitializingSingleton#afterSingletonsInstantiated() 方法,代表所有常规单例bean都已创建后的回调

@Override
public void preInstantiateSingletons() throws BeansException {
   //获取我们容器中所有bean定义的名称
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
   
   //循环我们所有的bean定义名称
   for (String beanName : beanNames) {
      //合并我们的bean定义
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      // 根据bean定义判断是不是抽象的&& 不是单例的 &&不是懒加载的
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {     //是不是工厂bean
            //是的话 给beanName+前缀&符号
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); // 通过&前缀返回的bean其实是FactoryBean子类的那个bean,并不是FactoryBean#getObject()返回的那个bean
            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());
               }
               //调用真正的getBean的流程
               if (isEagerInit) {
                  // 这里的beanName没有加&前缀,说明拿到的是FactoryBean#getObject()返回的那个bean
                  getBean(beanName);
               }
            }
         } else {   //非工厂Bean 就是普通的bean
            getBean(beanName);
         }
      }
   }
   
   //或有的bean的名称 ...........到这里所有的单实例的bean已经记载到单实例bean到缓存中
   for (String beanName : beanNames) {
      //从单例缓存池中获取所有的对象
      Object singletonInstance = getSingleton(beanName);
      //判断当前的bean是否实现了SmartInitializingSingleton接口
      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. 遍历spring中所有的beanName,如果该beanName对应的bean实现了SmartFactoryBean接口且isEagerInit()返回true,那说明该FactoryBean渴望初始化,调用getBean(beanName)获取真正的bean(这里的beanName没有加&前缀,说明拿到的最终是FactoryBean#getObject()返回的那个bean);如果是普通的bean,调用getBean(beanName)生成bean(如果不清楚getBean()时加不加&可以看下面的demo)
  2. 至此,spring容器中所有的单例bean都已经被生成保存到spring缓存中了
  3. 遍历spring中所有的bean,如果它实现了SmartInitializingSingleton接口,就回调SmartInitializingSingleton#afterSingletonsInstantiated()方法代表所有常规单例bean都已创建后的回调

DEMO:getBean()时加不加&返回的bean分别是什么

@Component
public class MyTestBean implements FactoryBean<MyTestBean> {
    private String name;

    //返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中。
    @Override
    public MyTestBean getObject() throws Exception {
        MyTestBean bean = new MyTestBean();
        bean.setName("Tom");
        return bean;
    }
    @Override
    public Class<?> getObjectType() {
        return  MyTestBean.class; //返回FactoryBean创建的bean类型。 
    }
    @Override
    public boolean isSingleton() {
        return true; //返回由FactoryBean创建的bean实例的作用域是singleton还是prototype。 
    }
}

这里MyTestBean实现了FactoryBean接口,这个时候我们getBean(“myTestBean”)得到的就是getObject()返回的对象(注意:这个返回的对象不一定就是当前类的这个对象,也就是说可以不是MyTestBean对象,根据自己的需求可以是其他的),走FactoryBean它定义的getObject()方法;所以最后打印的name自然是Tom。

如果非要得到MyTestBean对象(就是不取getObject()返回的那个对象)可以在getBean的时候前面多加一个"&"。

12. finishRefresh();

最后容器刷新,发布刷新事件(Spring cloud也是从这里启动的)

protected void finishRefresh() {
   // Clear context-level resource caches (such as ASM metadata from scanning).
   clearResourceCaches();
   
   // 为spring容器创建一个LifecycleProcessor,用于启动spring中那些实现了Lifecycle接口的bean
   initLifecycleProcessor();

   // Propagate refresh to lifecycle processor first.
   getLifecycleProcessor().onRefresh();
   
   // 发布容器刷新完成事件ContextRefreshedEvent
   publishEvent(new ContextRefreshedEvent(this));

   // Participate in LiveBeansView MBean, if active.
   // 忽略,跟mbean有关
   LiveBeansView.registerApplicationContext(this);
}

12.1 initLifecycleProcessor();

为spring容器创建一个LifecycleProcessor,默认是DefaultLifecycleProcessor,它其实本质上也实现了Lifecycle接口,只不过它负责启动spring容器中所有实现了Lifecycle接口的类

protected void initLifecycleProcessor() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
      this.lifecycleProcessor =
            beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
   } else {
      DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
      defaultProcessor.setBeanFactory(beanFactory);
      this.lifecycleProcessor = defaultProcessor;
      beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
   }
}

12.2 getLifecycleProcessor().onRefresh();

调用DefaultLifecycleProcessoronRefresh()方法,很简单,具体逻辑如下:

  1. 获取spring中所有实现了Lifecycle接口的bean
  2. 如果该bean实现了SmartLifecycle接口且((SmartLifecycle)bean).isAutoStartup())返回true(说明该bean会自动调用start()方法完成自启动),那就调用该bean的start()方法

refresh()总结

1、prepareRefresh()刷新前的预处理;
   0)、this.closed.set(false),this.active.set(true)  设置一些标记位
   1)、initPropertySources()初始化一些属性设置;(交由子类去实现,比如web容器中的 AbstractRefreshableWebApplicationContext 就去初始化了servlet的一些init参数等等)
   2)、getEnvironment().validateRequiredProperties();检验属性的合法等
   3)、earlyApplicationEvents= new LinkedHashSet<ApplicationEvent>();初始化容器,保存一些早期的事件;
   
2、obtainFreshBeanFactory();获取BeanFactory;
   1)、refreshBeanFactory();抽象方法,子类【AbstractRefreshableApplicationContext】唯一实现的:
         ①、若已经存在beanFactory了,那就做一些清理工作(销毁单例Bean、关闭工厂)
         ②、创建了一个this.beanFactory = new DefaultListableBeanFactory();并且设置id
         ③、把旧的工厂的属性赋值给新创建的工厂:customizeBeanFactory(beanFactory)
         ④、loadBeanDefinitions(beanFactory):加载Bean定义。抽象方法,由子类去决定从哪儿去把Bean定义加载进来,实现有比如:
               XmlWebApplicationContext:专为web设计的从xml文件里加载Bean定义(借助XmlBeanDefinitionReader)
               ClassPathXmlApplicationContext/FileSystemXmlApplicationContext:均由父类AbstractXmlApplicationContext去实现这个方法的,也是借助XmlBeanDefinitionReader
               AnnotationConfigWebApplicationContext:基于注解驱动的容器。(也是当下最流行、最重要的一个实现,前面一篇博文对此有重点分析),借助了AnnotatedBeanDefinitionReader.register()方法加载Bean定义
                  (这里面需要注意的是:.register()只是把当前这一个Class对象registry.registerBeanDefinition()了,至于内部的@Bean@ComponentScan扫描到的,都不是在此处注册的)
                  
               有必要说一句:AnnotationConfigApplicationContext是在非web环境下的容器。它虽然没有实现实现loadBeanDefinitions()抽象方法,是因为它在new对象的时候,已经调用了.register()完成配置Bean定义信息的注册了
   2)、getBeanFactory();返回刚才GenericApplicationContext创建的BeanFactory对象;
   3)、将创建的BeanFactory【DefaultListableBeanFactory】返回;
   =======到这一步截止,BeanFactory已经创建好了(只不过都还是默认配置而已),配置Bean的定义信息也注册好了=======
   
3、prepareBeanFactory(beanFactory);BeanFactory的预准备工作(对BeanFactory进行一些设置);
   1)、设置BeanFactory的类加载器、StandardBeanExpressionResolver、ResourceEditorRegistrar
   2)、添加感知后置处理器BeanPostProcessor【ApplicationContextAwareProcessor】,并设置一些忽略EnvironmentAware、EmbeddedValueResolverAware、xxxxx(因为这个处理器都一把抓了)
   3)、注册【可以解析的(表示虽然不在容器里,但还是可以直接 @Auwowired)】自动装配;我们能直接在任何组件中自动注入(@Autowired):
         BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
   5)、添加BeanPostProcessor【ApplicationListenerDetector】 检测注入进来的Bean是否是监听器
   6)、Detect a LoadTimeWeaver and prepare for weaving, if found.添加编译时的AspectJ支持:LoadTimeWeaverAwareProcessor
      (添加的支持的条件是:beanFactory.containsBean("loadTimeWeaver"))
   7)、给BeanFactory中注册一些能用的组件;
      environment-->【ConfigurableEnvironment】、
      systemProperties-->【Map<String, Object>】、
      systemEnvironment-->【Map<String, Object>】

4、postProcessBeanFactory(beanFactory);BeanFactory准备工作完成后进行的后置处理工作;(由子类完成)
   一般web容器都会对应的实现此方法,比如 AbstractRefreshableWebApplicationContext:
      1)、添加感知BeanPostProcessor【ServletContextAwareProcessor】,支持到了ServletContextAware、ServletConfigAware
      2)、注册scopse:beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());当然还有SCOPE_SESSION、SCOPE_APPLICATION
      3)、向上线一样,注册【可以解析的】自动注入依赖:ServletRequest/ServletResponse/HttpSession/WebRequest
         (备注:此处放进容器的都是xxxObjectFactory类型,所以这是为何@Autowired没有线程安全问题的重要一步)
      4)、registerEnvironmentBeans:注册环境相关的Bean(使用的registerSingleton,是直接以单例Bean放到容器里面了)
         servletContext-->【ServletContext】
         servletConfig-->【ServletConfig】
         contextParameters-->【Map<String, String>】 保存有所有的init初始化参数(getInitParameter)
         contextAttributes-->【Map<String, Object>】 servletContext的所有属性(ServletContext#getAttribute(String))
         
========以上是BeanFactory的创建及预准备工作,至此准备工作完成了,那么接下来就得利用工厂干点正事了========

5、invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessor的方法;
   BeanFactoryPostProcessor:BeanFactory的后置处理器。此处调用,现在就表示在BeanFactory标准初始化之后执行的;
   两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor(子接口)
   1)、执行BeanFactoryPostProcessor们的方法;
   
      ===先执行BeanDefinitionRegistryPostProcessor===
      1)、获取所有的BeanDefinitionRegistryPostProcessor;(当然会最先执行我们手动set进去的Processor,但是这个一般都不会有)
      2)、先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、
         postProcessor.postProcessBeanDefinitionRegistry(registry)
      3)、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor
      4)、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors
      (小细节:都会调用getBean(“name”,BeanDefinitionRegistryPostProcessor.class)方法,所以都会先实例化,才去执行的)
      
      **这里面需要特别的介绍一个处理器:`ConfigurationClassPostProcessor`,它是一个BeanDefinitionRegistryPostProcessor**
      **它会解析完成所有的@Configuration配置类,然后所有@Bean@ComponentScan等等Bean定义都会搜集进来了,所以这一步是非常的重要的**
   
      ===再执行BeanFactoryPostProcessor的方法(顺序逻辑同上,略)===
   2)、再次检测一次添加对AspectJ的支持。为何还要检测呢?through an @Bean method registered by ConfigurationClassPostProcessor,这样我们注入了一个切面Bean,就符合条件了嘛
      
6、registerBeanPostProcessors(beanFactory);注册BeanPostProcessor(Bean的后置处理器)【 intercept bean creation】
      **不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的**
      BeanPostProcessor:BeanPostProcessor是一个工厂钩子,允许Spring框架在新创建Bean实例时对其进行定制化修改,比如填充Bean、创建代理、解析Bean内部的注解等等。。。
      DestructionAwareBeanPostProcessor:Bean销毁时候
      InstantiationAwareBeanPostProcessor:Bean初始化的时候
      SmartInstantiationAwareBeanPostProcessor:初始化增强版本:增加了一个对Bean类型预测的回调(一般是Spring内部使用,调用者还是使用InstantiationAwareBeanPostProcessor就好)
      MergedBeanDefinitionPostProcessor:合并处理Bean定义的时候的回调【该类型的处理器保存在名为internalPostProcessors的List中】、
      
      1)、获取所有的 BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级
      2)、先注册PriorityOrdered优先级接口的BeanPostProcessor;
         把每一个BeanPostProcessor;添加到BeanFactory中
         beanFactory.addBeanPostProcessor(postProcessor);
      3)、再注册Ordered接口的、最后注册没有实现任何优先级接口的、最终注册MergedBeanDefinitionPostProcessor
         (此处细节:BeanPostProcessor本身也是一个Bean,其注册之前一定先实例化,而且是分批实例化和注册。
         另外还有一个非常非常重要的一点就是阶段顺序问题:
         我们可以把BeanPostProcessor的实例化与注册分为四个阶段:
               第一阶段applicationContext内置阶段、
               第二阶段priorityOrdered阶段、
               第三阶段Ordered阶段、
               第四阶段nonOrdered阶段
         因为是分批注册,所以我们同阶段是不能拦截到同阶段的BeanPostProcessor的实例化的。举例子:
         PriorityOrdered的只能被内置阶段的比如:ApplicationContextAwareProcessor(可以注入啦)/ApplicationListenerDetector(可以接受事件啦)这种拦截
         而:Ordered就可以被  内置的、PriorityOrdered都拦截到了
         。。。 以此类推。。。
         
         所以我们的BeanPostProcessor是可以@Autowired 比如Service、Dao来做一些事的。单思,但是一定要【注意避免BeanPostProcessor启动时的“误伤”陷阱】,什么意思?大概解释一下如下:
            可能由于你的Processor依赖于某个@Bean,从而让它提前实例化了,然后就很可能错过了后面一些BeanPostProcessor的处理,造成“误伤”
            (SpringBoot中使用Shiro、Spring-Cache的时候,使用不当会出现这样的问题)
   
      6)、这一步非常有意思:moving it to the end of the processor chain。它的又注册了一次,作用是把这个探测器移动到处理器的底部,最后一个(显然,最后一个是为了不要放过任何Bean)
         (小细节:可能有小伙伴疑问,这里也是new出来,这这样容器内不就有两个探测器对象了吗?气其实不然,ApplicationListenerDetector它重写了hashCode方法,且只和应用applicationContext有关)
         return ObjectUtils.nullSafeHashCode(this.applicationContext);所以对它执行remove的时候,会被当作同一个对象处理,能把老的移除成功添加新的的

7、initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
      1)、看容器中是否有id为messageSource的,类型是MessageSource的组件
         如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource;
            MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;
      2)、把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource
      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)
      
8、initApplicationEventMulticaster();初始化事件派发器;
      1)、从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
      2)、如果上一步没有配置;创建一个SimpleApplicationEventMulticaster,将创建的ApplicationEventMulticaster添加到BeanFactory中
      
9、onRefresh();留给子容器(子类) 容器刷新的时候做些事
      AbstractRefreshableWebApplicationContext:this.themeSource = UiApplicationContextUtils.initThemeSource(this);
      
10、registerListeners();把容器中将所有项目里面的ApplicationListener注册进来;
      1、拿到容器里所有的Bean定义的名字,类型为ApplicationListener,然后添加进来
         getApplicationEventMulticaster().addApplicationListener(listener);
      2、派发之前步骤产生的事件(早期事件)
      (细节:此处只是把Bean的名字放进去,Bean还没有实例化哦~~~~)

11、finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean;这应该是最核心的一步了
   1)、为容器初始化ConversionService(容器若没有就不用初始化了,依然采用getBean()初始化的) 提供转换服务
   2)、若没有设置值解析器,那就注册一个默认的值解析器(lambda表示的匿名处理)
   3)、实例化LoadTimeWeaverAware(若存在)
   4)、清空临时类加载器:beanFactory.setTempClassLoader(null)
   5)、缓存(快照)下当前所有的Bean定义信息 beanFactory.freezeConfiguration();
   ==== 更精确的是说是根据Bean的定义信息:beanDefinitionNames来实例化、初始化剩余的Bean ====
   6)、beanFactory.preInstantiateSingletons();初始化后剩下的单实例bean(过程这里就不详说了)
   
12、finishRefresh();完成BeanFactory的初始化创建工作;IOC容器就创建完成
      0)、clearResourceCaches(); (Spring5.0才有)
      1)、initLifecycleProcessor();初始化和生命周期有关的后置处理器;从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();
         关于Lifecycle接口的使用,也专门讲解过,这里不聊了
      2)、getLifecycleProcessor().onRefresh();  相当于上面刚注册,下面就调用了
      3)、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;
      4)、liveBeansView.registerApplicationContext(this); 和MBean相关,略
   
   ======总结===========
   1)、Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息(可以有N种方式);
      1)、xml注册bean;<bean>
      2)、注解注册Bean;@Service@Component@Bean、xxx
   2)、Spring容器会合适的时机创建这些Bean
      1)、用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
      2)、统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();
   3)、后置处理器;BeanPostProcessor
      1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
         AutowiredAnnotationBeanPostProcessor:处理自动注入
         AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
         xxx....
         增强的功能注解:
         AsyncAnnotationBeanPostProcessor
         ....
   4)、事件驱动模型;
      ApplicationListener;事件监听;
      ApplicationEventMulticaster;事件派发: