四、SpringBoot源码学习--容器的刷新-加载bean

SpringBoot通过ConfigurableApplicationContext的run方法对应用服务进行启动,在run方法中调用ConfigurableApplicationContext类的refreshContext方法实现容器对bean的加载。

一、 实现bean加载的方法:refresh()

容器对bean的加载主要是在实现了ConfigurableApplicationContext接口的类的refresh方法中。

在ConfigurableApplicationContext的方法中的注释如下:

/**
* Load or refresh the persistent representation of the configuration, which
* might be from Java-based configuration, an XML file, a properties file, a
* relational database schema, or some other format.
* 

As this is a startup method, it should destroy already created singletons * if it fails, to avoid dangling resources. In other words, after invocation * of this method, either all or no singletons at all should be instantiated. * @throws BeansException if the bean factory could not be initialized * @throws IllegalStateException if already initialized and multiple refresh * attempts are not supported */ void refresh() throws BeansException, IllegalStateException;

这个方法会从xml、properties、关系数据库或者其他类型的java配置中加载配置属性。refresh()的主要作用是启动的应用的。而且此方法在创建某一个单例失败的时候,为了避免悬空资源的出现,会销毁所有已经创建的单例。也就是说,这些需要被创建的单例要么全部实例化,要么不实例化任何一个。

二、spring-context包的AbstractApplicationContext抽象类

1. refresh()源码

在实现ConfigurableApplicationContext接口的AbstractApplicationContext类(这个类是spring boot启动过程中,使用的最为关键的一个类,他是spring framework框架中spring-context包下的一个抽象类)中,它的代码如下:

public abstract class AbstractApplicationContext extends DefaultResourceLoader
      implements ConfigurableApplicationContext {

    ......

    @Override
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
          // Prepare this context for refreshing.
          //准备刷新的容器环境
          prepareRefresh();

          // Tell the subclass to refresh the internal bean factory.
          //让AbstractApplicationContext的子类刷新内置的bean工厂(实际就是创建一个bean工厂)
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

          // Prepare the bean factory for use in this context.
          //配置bean工厂,bean工厂的前置增强器
          prepareBeanFactory(beanFactory);

          try {
             // Allows post-processing of the bean factory in context subclasses.
             //bean工厂的后置增强器,上面对bean工厂进行了许多配置,现在需要对bean工厂进行一些处理,允许bean工厂的后置增强进入AbstractApplicationContext的子类
             //1.添加一个ServletContextAwareProcessor到bean工厂中。
             //2.在bean工厂自动装配的时候忽略一些接口。如:ServletContextAware、ServletConfigAware
             //3.注册WEB应用特定的域(scope)到bean工厂中,以便WebApplicationContext可以使用它们。比如"request", "session", "globalSession", "application",
             //4.注册WEB应用特定的Environment bean到bean工厂中,以便WebApplicationContext可以使用它们。如:"contextParameters", "contextAttributes"
             postProcessBeanFactory(beanFactory);

             // Invoke factory processors registered as beans in the context.
             //调用所有注册到bean工厂的bean工厂增强器,以对bean工厂进行一些处理。这个方法必须在所有的singleton初始化之前调用。
             invokeBeanFactoryPostProcessors(beanFactory);

             // Register bean processors that intercept bean creation.
             //注册bean的后置增强器,此方法只是注册,并没有对增强器进行调用,真正调用是在bean的实例化过程中
             //处理过程和invokeBeanFactoryPostProcessors类似,只是多了一个MergedBeanDefinitionPostProcessor接口的处理
             //注册用来拦截bean创建的BeanPostProcessor bean.这个方法需要在所有的application bean初始化之前调用。
             // 把这个注册的任务委托给了PostProcessorRegistrationDelegate来完成。
             registerBeanPostProcessors(beanFactory);

             // Initialize message source for this context.
             //初始化MessageSource接口的一个实现类。这个接口提供了消息处理功能。主要用于国际化/i18n
             initMessageSource();

             // Initialize event multicaster for this context.
             //为这个context初始化一个事件广播器(ApplicationEventMulticaster)。
             initApplicationEventMulticaster();

             // Initialize other special beans in specific context subclasses.
             //在AbstractApplicationContext的子类中初始化其他特殊的bean。其实就是初始化ThemeSource接口的实例。这个方法需要在所有单例bean初始化之前调用。
             onRefresh();

             // Check for listener beans and register them.
             //注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的。
             // 这不会影响到其它监听器bean。在注册完以后,还会将其前期的事件发布给相匹配的监听器。
             registerListeners();

             // Instantiate all remaining (non-lazy-init) singletons.
             //完成bean工厂的初始化工作。这一步非常复杂,也非常重要,涉及到了bean的创建。第二步中只是完成了BeanDefinition的定义、解析、处理、注册。
             // 但是还没有初始化bean实例。这一步将初始化所有非懒加载的单例bean。
             finishBeanFactoryInitialization(beanFactory);

             // Last step: publish corresponding event.
             //完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)。
             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();
      }
   }

    ......

}

可以看到,容器在加载bean的时候,需首先需要创建一个bean工厂,再对这个bean工厂进行初始化、增强等操作,随后根据配置将系统配置的bean注册到工厂中,然后在invokeBeanFactoryPostProcessors方法中,实例化所有注册到工厂的bean(包括系统配置的bean、监听器、事件广播器,以及一些非懒加载的bean等),最后一部对容器进行刷新。

2. refresh()流程

主体流程如下:

1. 准备刷新的容器环境

这一步调用prepareRefresh()方法,是context容器刷新前的准备工作,将会设置context的启动日期和活动标志,以及执行属性源的任何初始化。

protected void prepareRefresh() {
   // Switch to active.
   //context的启动日期
   this.startupDate = System.currentTimeMillis();
   //设置context的当前状态
   this.closed.set(false);
   //设置活动状态
   this.active.set(true);
   //输出debug日志
   if (logger.isDebugEnabled()) {
      if (logger.isTraceEnabled()) {
         logger.trace("Refreshing " + this);
      }
      else {
         logger.debug("Refreshing " + getDisplayName());
      }
   }
   // Initialize any placeholder property sources in the context environment.
   //初始化context环境(初始化context environment中的占位符属性来源,由其子类完成)
   initPropertySources();
   // Validate that all properties marked as required are resolvable:
   // see ConfigurablePropertyResolver#setRequiredProperties
   //验证所有必须的属性
   getEnvironment().validateRequiredProperties();
   // Store pre-refresh ApplicationListeners...
   //存储刷新前的application监听器
   if (this.earlyApplicationListeners == null) {
      this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
   }
   else {
      // Reset local application listeners to pre-refresh state.
      //重置本地application监听器的刷新前的状态
      this.applicationListeners.clear();
      this.applicationListeners.addAll(this.earlyApplicationListeners);
   }
   // Allow for the collection of early ApplicationEvents,
   // to be published once the multicaster is available...
   //刷新事件广播器
   this.earlyApplicationEvents = new LinkedHashSet<>();
}

2. 让AbstractApplicationContext的子类刷新内置的bean工厂(实际就是创建一个bean工厂)

由其子类完成,子类它通过委派给beanDifinition reader,把beanDefinition加载到工厂中,最后把创建好的bean工厂交给context进行管理。

@Override
protected final void refreshBeanFactory() throws BeansException {
   //存在bean工厂则关闭
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      //创建bean工厂
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      //设置bean工厂的序列号
      beanFactory.setSerializationId(getId());
      //根据context自定义bean工厂
      customizeBeanFactory(beanFactory);
      //通过委派给bd reader,把bd加载到bean工厂中
      loadBeanDefinitions(beanFactory);
      //把创建好的bean工厂交给context管理
      this.beanFactory = beanFactory;
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

3. 配置bean工厂,bean工厂的前置增强器

这一步会配置工厂的标准属性,例如context的类加载器和后置增强器。执行流程如下:

(1) 设置bean工厂的类加载器(使用context的类加载器)

(2) 设置bean工厂的bean表达式解析器

(3) 添加bean工厂的资源属性编辑器

(4) 添加bean工厂的ApplicationContextAwareProcessor,根据不同的类型加入不同的属性

(5) 忽略实现以下接口类型的自动装配

  • EnvironmentAware 如果bean要设置运行时的Environment,则需要实现此接口
  • EmbeddedValueResolverAware 如果bean需要设置解析字符串的策略,则需要实现此接口
  • ResourceLoaderAware 如果bean需要设置资源加载器,则需要实现此接口
  • ApplicationEventPublisherAware 如果bean需要实现事件发布功能,则需要实现此接口
  • MessageSourceAware 如果bean需要解析消息的策略接口(支持此类消息的参数化和国际化),则需要实现此接口
  • ApplicationContextAware 如果bean需要设置ApplicationContext,则需要实现此接口

(6) 注册实现以下接口的依赖类型和自动装配的类

  • BeanFactor 用于访问Springbean容器。
  • ResourceLoader 用于加载资源
  • ApplicationEventPublisher 用于事件发布的接口
  • ApplicationContext 为应用程序提供配置的接口。

(7) 注册检查内部bean的后置增强器-ApplicationListeners

如果bean是ApplicationListener,则加入到事件派发器中

(8) 增加对AspectJ(AOP编程思想的一个扩展)的支持

(9) 注册默认的环境bean

4. bean工厂的后置增强器

上面对bean工厂进行了许多配置,现在需要对bean工厂进行一些处理,允许bean工厂的后置增强进入AbstractApplicationContext的子类。例如子类AbstractRefreshableWebApplicationContext主要做了如下的操作

(1) 添加一个ServletContextAwareProcessor到bean工厂中。

(2) 在bean工厂自动装配的时候忽略一些接口。如:ServletContextAware、ServletConfigAware

(3) 注册WEB应用特定的域(scope)到bean工厂中,以便WebApplicationContext可以使用它们。比如"request", "session", "globalSession", "application",

(4) 注册WEB应用特定的Environment bean到bean工厂中,以便WebApplicationContext可以使用它们。如:"contextParameters", "contextAttributes"

5. 调用所有注册到bean工厂的bean工厂增强器

以对bean工厂进行一些处理。这个方法必须在所有的singleton初始化之前调用。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   //主要是通过这行代码来对后置增强器进行调用
   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)
   //检测LoadTimeWeaver并准备编织切面类(AOP,如果同时发现)
   //例如通过ConfigurationClassPostProcessor注册的使用@Bean注解的方法
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

其中invokeBeanFactoryPostProcessors会对加载到bean工厂中的bean进行实例化操作,是在beanFactory.getBean()中完成的。

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) 
   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
   //用来保存被处理过的bean的名字
   Set processedBeans = new HashSet<>();
   //如果bean工厂是bd注册器
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List regularPostProcessors = new ArrayList<>();
      List registryProcessors = new ArrayList<>();

      //遍历context中的bean工厂后置增强器list,由AbstractApplicationContext的子类的addBeanFactoryPostProcessor的添加
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         //如果bean工厂后置增强器是db注册器的后置增强器
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            //对bean工厂进行后置增强
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            //db注册器的后置增强器添加到这侧器的后置增强器list
            registryProcessors.add(registryProcessor);
         }
         else {
            //保存常规的bean工厂后置增强器
            regularPostProcessors.add(postProcessor);
         }
      }

      // Do not initialize FactoryBeans here: We need to leave all regular beans
      // uninitialized to let the bean factory post-processors apply to them!
      // Separate between BeanDefinitionRegistryPostProcessors that implement
      // PriorityOrdered, Ordered, and the rest.
      // 要在这里初始化FactoryBeans:我们需要让所有常规bean保持未初始化状态,
      // 以便让bean factory后处理器应用于它们!
      // 在实现PriorityOrdered、Ordered和rest接口的不同bd注册器的后置增强器之间进行分离。
      List currentRegistryProcessors = new ArrayList<>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      //先执行实现PriorityOrdered接口的bd注册器的后置增强器
      //拿到bd注册器的后置增强器名字
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      //遍历,如果实现PriorityOrdered接口,添加到currentRegistryProcessors中,并添加到processedBeans
      //先处理PriorityOrdered 再处理Ordered,是因为PriorityOrdered接口继承了Ordered接口
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//对bean进行实例化
            processedBeans.add(ppName);
         }
      }
      //排序
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      //执行
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      //清空
      currentRegistryProcessors.clear();

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
      //再执行实现Ordered接口的bd注册器的后置增强器
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//对bean进行实例化
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
      //最后执行剩余所有的bd注册器的后置增强器
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName)) {
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//对bean进行实例化
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
      //调用所有已经执行过增强的bean工厂后置增强器
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }
   //如果bean工厂不是bd注册器
   else {
      // Invoke factory processors registered with the context instance.
      //执行在上下文实例中注册的工厂处理器
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let the bean factory post-processors apply to them!
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);


   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List priorityOrderedPostProcessors = new ArrayList<>();
   List orderedPostProcessorNames = new ArrayList<>();
   List nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
         //之前已经执行过的,跳过
      }
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         //实现PriorityOrdered接口的
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));//对bean进行实例化
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         //实现Ordered接口的
         orderedPostProcessorNames.add(ppName);
      }
      else {
         //其他的
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
   List orderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));//对bean进行实例化
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // Finally, invoke all other BeanFactoryPostProcessors.
   List nonOrderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));//对bean进行实例化
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

   // Clear cached merged bean definitions since the post-processors might have
   // modified the original metadata, e.g. replacing placeholders in values...
   //清除合并bd的缓存,因为后后置增强器可能修改了原始元数据,例如替换值中的占位符。。。
   beanFactory.clearMetadataCache();
}

6. 注册bean的后置增强器

此方法只是注册,并没有对增强器进行调用,真正调用是在bean的实例化过程中。且它的处理过程和invokeBeanFactoryPostProcessors类似,只是多了一个MergedBeanDefinitionPostProcessor接口的处理。注册用来拦截bean创建的BeanPostProcessor bean。这个方法需要在所有的application bean初始化之前调用。把这个注册的任务委托给了PostProcessorRegistrationDelegate来完成。

7. 初始化MessageSource接口的一个实现类

这个接口提供了消息处理功能。主要用于国际化/i18n。

8. 为这个context初始化一个事件广播器(ApplicationEventMulticaster)

9. 在AbstractApplicationContext的子类中实现onRefresh此方法,用来初始化其他特殊的bean

其实就是初始化ThemeSource接口的实例。这个方法需要在所有单例bean初始化之前调用。

10. 注册应用的监听器

就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的。

11. 完成bean工厂的初始化工作

这一步非常复杂,也非常重要,涉及到了bean的创建。第二步中只是完成了BeanDefinition的定义、解析、处理、注册。但是还没有初始化bean实例。这一步将初始化所有非懒加载的单例bean。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   //初始化上下文的转换服务,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));
   }


   // 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.
   // 设置一个内置的值处理器(若没有的话),该处理器作用有点像一个PropertyPlaceholderConfigurer bean
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }


   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   // 注意此处已经调用了getBean方法,初始化LoadTimeWeaverAware Bean,实际上是对Bean的实例化
   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.
   // 缓存(冻结)所有的bean definition数据,不期望以后会改变
   beanFactory.freezeConfiguration();


   // Instantiate all remaining (non-lazy-init) singletons.
   // 这个就是最重要的方法:会把留下来的Bean们  不是lazy懒加载的bean都实例化掉
   beanFactory.preInstantiateSingletons();
}

在finishBeanFactoryInitialization方法中,最核心的就是beanFactory.preInstantiateSingletons()。通过该方法,会将所有剩余未实例化的bean通过doGetBean进行实例化( 部分Bean在invokeBeanFactoryPostProcessors通过getBean()进行实例化,还有些bean直接通过addSingleton()直接添加,其余的bean在finishBeanFactoryInitialization的beanFactory.preInstantiateSingletons进行实例化)。

@Override
public void preInstantiateSingletons() throws BeansException {
   if (logger.isTraceEnabled()) {
      logger.trace("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.
   // 此处目的,把所有的bean定义信息名称,赋值到一个新的集合中
   List beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

       不是抽象类&&是单例&&不是懒加载
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         // 这是Spring提供的对工程bean模式的支持:比如第三方框架的继承经常采用这种方式
         // 如果是工厂Bean,那就会此工厂Bean放进去
         if (isFactoryBean(beanName)) {
            // 拿到工厂Bean本省,注意有前缀为:FACTORY_BEAN_PREFIX
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               FactoryBean factory = (FactoryBean) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged(
                        (PrivilegedAction) ((SmartFactoryBean) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean) factory).isEagerInit());
               }
               // true:表示渴望马上被初始化的,那就拿上执行初始化~
               if (isEagerInit) {
                  // 这里,就是普通单例Bean正式初始化了 核心逻辑在方法doGetBean中
                  getBean(beanName);
               }
            }
         }
         else {
            getBean(beanName);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans...
   // SmartInitializingSingleton:所有非lazy单例Bean实例化完成后的回调方法 Spring4.1才提供
   //SmartInitializingSingleton的afterSingletonsInstantiated方法是在所有单例bean都已经被创建后执行的
   //InitializingBean#afterPropertiesSet 是在仅仅自己被创建好了执行的
   // 比如EventListenerMethodProcessor它在afterSingletonsInstantiated方法里就去处理所有的Bean的方法
   // 看看哪些被标注了@EventListener注解,提取处理也作为一个Listener放到容器addApplicationListener里面去
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            // 比如:ScheduledAnnotationBeanPostProcessor CacheAspectSupport  MBeanExporter等等
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
} 
  

12. 完成context的刷新

主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)。

三、总结

容器的刷新过程主要包含:1.资源加载(通过资源加载器实现Resource接口,来对BeanDifinition进行资源定位)、beanDefinition的加载(这个过程会把定义好的bean表示成ioc容器内部统一的的数据结构--beanDefinition)和beanDefinition的注册(最后将定义好的beanDefinition注册到ioc容器特定的hashmap中)三个过程。

你可能感兴趣的:(spring-boot,源码学习,spring,boot,容器,后端)