spring boot 源码解析9-SpringApplication#run第9步

前言

我们来到了SpringApplication#run方法的第9步,这步做的工作比较多.我们慢慢来.

分析

第9步执行的是如下代码:

private void refreshContext(ConfigurableApplicationContext context) {
        refresh(context);
        // 注册一个关闭容器时的钩子函数
        if (this.registerShutdownHook) {
            try {
                context.registerShutdownHook();
            }
            catch (AccessControlException ex) {
                // Not allowed in some environments.
            }
        }
    }

2件事

  1. 调用AbstractApplicationContext#refresh 完成初始化.
  2. 注册一个关闭容器时的钩子函数,如果registerShutdownHook 为true的话,默认是true.

  3. AbstractApplicationContext#refresh 代码如下:

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
    
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
    
            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);
    
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
    
                // Initialize message source for this context.
                initMessageSource();
    
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
    
                // Initialize other special beans in specific context subclasses.
                onRefresh();
    
                // Check for listener beans and register them.
                registerListeners();
    
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
    
                // Last step: publish corresponding event.
                finishRefresh();
            }
    
            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }
    
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
    
                // Reset 'active' flag.
                cancelRefresh(ex);
    
                // Propagate exception to caller.
                throw ex;
            }
    
            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

    做了13件事:

    1. 调用 prepareRefresh 进行刷新的准备
    2. 初始化BeanFactory
    3. 对bean factory进行各种功能填充 @Qualifler与@Autowired就是在这一步骤增加支持
    4. 扩展点,postProcessBeanFactory 子类覆盖方法做额外的处理
    5. 激活各种BeanFactory处理器
    6. 注册拦截bean创建的bean处理器,这里只是注册,真正的调用是在getBean的时候
    7. 为上下文初始化MessageSource,即国际化处理
    8. 初始化ApplicationEventMulticaster,并放入ApplicationEventMulticaster bean中
    9. 扩展点,onRefresh,留个子类来初始化其他的bean
    10. 在所有注册的bean中查找listener beans,注册到消息广播器中
    11. 初始化剩下的单例(non-lazy-init)
    12. 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出contextRefreshEvent通知别人
    13. 清除缓存

    我们分别来进行解析.

    1. prepareRefresh 执行的是AnnotationConfigEmbeddedWebApplicationContext#prepareRefresh,代码如下:

      protected void prepareRefresh() {
          this.scanner.clearCache();
          super.prepareRefresh();
      }

      2件事:

      1. 清空ClassPathBeanDefinitionScanner的缓存.执行如下代码:

        public void clearCache() {
            if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
                ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
            }
        }

        由于ClassPathBeanDefinitionScanner 中的metadataReaderFactory 是CachingMetadataReaderFactory的子类,因此会强转为CachingMetadataReaderFactory调用其clearCache.代码如下:

        public void clearCache() {
                synchronized (this.metadataReaderCache) {
                    this.metadataReaderCache.clear();
                }
        }

        清空class metadata 的缓存

      2. 调用其父类的AbstractApplicationContext的prepareRefresh方法.代码如下:

        protected void prepareRefresh() {
            this.startupDate = System.currentTimeMillis();
            this.closed.set(false);
            this.active.set(true);
            if (logger.isInfoEnabled()) {
                logger.info("Refreshing " + this);
            }
            // Initialize any placeholder property sources in the context environment
            initPropertySources();
            // Validate that all properties marked as required are resolvable
            // see ConfigurablePropertyResolver#setRequiredProperties
            getEnvironment().validateRequiredProperties();
            // Allow for the collection of early ApplicationEvents,
            // to be published once the multicaster is available...
            this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
        }
        

        5件事

        1. 将startupDate设为当前时间,closed 设为false,active 设为true。
        2. 打印日志.如下:

          2017-12-25 15:53:15.384  INFO 53253 — [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@cb0755b: startup date [Mon Dec 25 15:53:09 CST 2017]; root of context hierarchy

        3. 调用 initPropertySources 这个方法,该方法是个扩展点,最终会调用GenericWebApplicationContext#initPropertySources,代码如下:

          protected void initPropertySources() {
              ConfigurableEnvironment env = getEnvironment();
              if (env instanceof ConfigurableWebEnvironment) {
                  ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
              }
          }

          最终会调用StandardServletEnvironment#initPropertySources方法.代码如下:

          WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);

          调用

          public static void initServletPropertySources(
          MutablePropertySources propertySources, ServletContext servletContext, ServletConfig servletConfig) {
          Assert.notNull(propertySources, "'propertySources' must not be null");
          if (servletContext != null && propertySources.contains(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) &&          propertySources.get(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) instanceof StubPropertySource) {
          propertySources.replace(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME,new ServletContextPropertySource(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME, servletContext));
          }
          if (servletConfig != null && propertySources.contains(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME)&&propertySources.get(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME) instanceof StubPropertySource) {
          propertySources.replace(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME,new ServletConfigPropertySource(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME, servletConfig));
          }
          }
          
          1. 判断如果servletContext 不等null并且propertySources包含servletContextInitParams的定义并且是StubPropertySource的子类的话,就替换为ServletContextPropertySource.
          2. 判断如果servletConfig 不等于null 并且 propertySources 包含servletConfigInitParams的 定义并且是StubPropertySource的子类的话,就替换为ServletConfigPropertySource.

          很明显,这里传入的servletContext, servletConfig都是null,因此不会执行.

        4. 获得Environment,检查是否存在 RequiredProperties 不存在的情况.当前获得的Environment为StandardServletEnvironment.其validateRequiredProperties实现如下:

          public void validateRequiredProperties() throws MissingRequiredPropertiesException {
          this.propertyResolver.validateRequiredProperties();
          }

          调用

              public void validateRequiredProperties() {
          MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
          for (String key : this.requiredProperties) {
          if (this.getProperty(key) == null) {
          ex.addMissingRequiredProperty(key);
          }
          }
          if (!ex.getMissingRequiredProperties().isEmpty()) {
          throw ex;
          }
          }

          很明显,这里通过遍历requiredProperties,尝试去获取,如果获取不到,就抛出MissingRequiredPropertiesException异常.

        5. 实例化earlyApplicationEvents .

    2. 接下来执行obtainFreshBeanFactory方法来初始化BeanFactory.代码如下:

      protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
          refreshBeanFactory();
          ConfigurableListableBeanFactory beanFactory = getBeanFactory();
          if (logger.isDebugEnabled()) {
              logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
          }
          return beanFactory;
      }

      2件事:

      1. 调用refreshBeanFactory,初始化BeanFactory. 最终执行的是GenericApplicationContext#refreshBeanFactory,代码如下:

        protected final void refreshBeanFactory() throws IllegalStateException {
        if (!this.refreshed.compareAndSet(false, true)) {
        throw new IllegalStateException(
                "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
        }
        this.beanFactory.setSerializationId(getId());
        }

        2件事:

        1. 将refreshed设为true,如果设置失败,说明该方法重复调用了,抛出IllegalStateException.
        2. 为beanFactory设置SerializationId, 其id是由ContextIdApplicationContextInitializer#initialize 生成的,我们之前有分析过,生成的id如下:

          application:test:8881

          beanFactory#setSerializationId代码如下:

          public void setSerializationId(String serializationId) {
          if (serializationId != null) {
              serializableFactories.put(serializationId, new WeakReference<DefaultListableBeanFactory>(this));
          }
          else if (this.serializationId != null) {
              serializableFactories.remove(this.serializationId);
          }
          this.serializationId = serializationId;
          }
      2. 返回当前实体的BeanFactory属性,代码如下:

        public final ConfigurableListableBeanFactory getBeanFactory() {
        return this.beanFactory;
        }

        返回的是DefaultListableBeanFactory.

    3. 调用prepareBeanFactory方法.代码如下:

      protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      // Tell the internal bean factory to use the context's class loader etc.
      beanFactory.setBeanClassLoader(getClassLoader());
      beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
      beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
      
      // Configure the bean factory with context callbacks.
      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));
      
      // 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()));
      }
      
      // Register default environment beans.
      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());
      }
      }
      1. 设置beanFactory的ClassLoader为当前context的ClassLoader
      2. 设置ExpressionResolver为StandardBeanExpressionResolver
      3. beanFactory增加一个默认的PropertyEditor,主要是对bean的属性等设置管理的一个工具
      4. 添加BeanPostProcessor为ApplicationContextAwareProcessor
      5. 添加EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware 到忽略自动装配的接口中,当spring将ApplicationContextAwareProcessor注册后,那么在invokeAwareInterfaces中直接,调用的Aware类已经不是普通的bean了,如ResourceLoaderAware,那么需要在spring做bean的依赖注入时忽略它们。
      6. 将BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext,当注册了依赖解析后,例如当注册了BeanFactory的解析依赖后,当bean的属性注入的时候,一旦检测到属性为beanFactory类型便会将beanFactory的实例注入进去
      7. 增加对aspectJ的支持
      8. 添加默认的系统环境bean
    4. 执行扩展点–>postProcessBeanFactory 子类覆盖方法做额外的处理.最终执行的是AnnotationConfigEmbeddedWebApplicationContext#postProcessBeanFactory方法,代码如下:

          protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      super.postProcessBeanFactory(beanFactory);
      if (this.basePackages != null && this.basePackages.length > 0) {
          this.scanner.scan(this.basePackages);
      }
      if (this.annotatedClasses != null && this.annotatedClasses.length > 0) {
          this.reader.register(this.annotatedClasses);
      }
      }

      3件事:

      1. 调用父类EmbeddedWebApplicationContext#postProcessBeanFactory方法.给beanFactory添加一个WebApplicationContextServletContextAwareProcessor类型的BeanPostProcessor,并添加了一个忽略装配的接口ServletContextAware.WebApplicationContextServletContextAwareProcessor继承了ServletContextAwareProcessor,而ServletContextAwareProcessor的postProcessBeforeInitialization方法代码已经做了ServletContextAware该做的事情.代码如下:

            protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.addBeanPostProcessor(
            new WebApplicationContextServletContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        }
        
      2. 如果AnnotationConfigEmbeddedWebApplicationContext中的basePackages大于零的话,就调用ClassPathBeanDefinitionScanner#scan.

      3. 如果AnnotationConfigEmbeddedWebApplicationContext中的annotatedClasses大于零的话,就调用AnnotatedBeanDefinitionReader#register.

      对于当前的场景来说, basePackages, annotatedClasses 都是为null,因此是不会执行的.

    5. 激活各种BeanFactory处理器,执行如下代码:

          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)
          if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
              beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
              beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
          }
      }
      1. 调用PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors.
      2. 如果beanFactory.getTempClassLoader() 等于null并且 beanFactory含有loadTimeWeaver的定义的话,就向beanFactory添加一个LoadTimeWeaverAwareProcessor,然后设置TempClassLoader 为 ContextTypeMatchClassLoader.

      其中第一步获得的BeanFactoryPostProcessor 有如下:

      org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor, 
      org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor,
      org.springframework.boot.context.config.ConfigFileApplicationListener$PropertySourceOrderingPostProcessor

      PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors 代码如下:

      public static void invokeBeanFactoryPostProcessors(
              ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
      
          // Invoke BeanDefinitionRegistryPostProcessors first, if any.
          Set<String> processedBeans = new HashSet<String>();
      
          if (beanFactory instanceof BeanDefinitionRegistry) {
              BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
              List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
              List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
      
              for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                  if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                      BeanDefinitionRegistryPostProcessor registryProcessor =
                              (BeanDefinitionRegistryPostProcessor) postProcessor;
                      registryProcessor.postProcessBeanDefinitionRegistry(registry);
                      registryProcessors.add(registryProcessor);
                  }
                  else {
                      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.
              List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
      
              // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
              String[] postProcessorNames =
                      beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
              for (String ppName : postProcessorNames) {
                  if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                      processedBeans.add(ppName);
                  }
              }
              sortPostProcessors(currentRegistryProcessors, beanFactory);
              registryProcessors.addAll(currentRegistryProcessors);
              invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
              currentRegistryProcessors.clear();
      
              // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
              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));
                      processedBeans.add(ppName);
                  }
              }
              sortPostProcessors(currentRegistryProcessors, beanFactory);
              registryProcessors.addAll(currentRegistryProcessors);
              invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
              currentRegistryProcessors.clear();
      
              // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
              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));
                          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.
              invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
              invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
          }
      
          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<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
          List<String> orderedPostProcessorNames = new ArrayList<String>();
          List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
          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)) {
                  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<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
          for (String postProcessorName : orderedPostProcessorNames) {
              orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
          }
          sortPostProcessors(orderedPostProcessors, beanFactory);
          invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
      
          // Finally, invoke all other BeanFactoryPostProcessors.
          List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
          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();
      }
      1. 首先判断beanFactory 是否为BeanDefinitionRegistry 的实例

        1. 如果是的话,则遍历beanFactoryPostProcessors

          1. 如果beanFactoryPostProcessor 是BeanDefinitionRegistryPostProcessor子类的话,则调用其postProcessBeanDefinitionRegistry对BeanDefinitionRegistry进行处理,然后添加到registryProcessors中.
          2. 否则添加到regularPostProcessors中.

          3. 从beanFactory中获得实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的实例,添加到priorityOrderedPostProcessors中,排序后,调用invokeBeanDefinitionRegistryPostProcessors进行处理.

          4. 从beanFactory中获得实现了Ordered接口的BeanDefinitionRegistryPostProcessor的实例,添加到orderedPostProcessors中,排序后,调用invokeBeanDefinitionRegistryPostProcessors进行处理.
          5. 处理其它为处理过的BeanDefinitionRegistryPostProcessor.调用其postProcessBeanDefinitionRegistry,进行处理. 添加到registryPostProcessors,processedBeans中
          6. 依次遍历registryPostProcessors,regularPostProcessors,调用其postProcessBeanFactory进行处理.
        2. 如果不是,直接调用PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors进行处理.

        对于当前场景, beanFactory 是 BeanDefinitionRegistry 的子类.因此为执行1.1

      2. 从beanFactory中获得BeanFactoryPostProcessor的Name.

      3. 对postProcessor进行分类

        1. 如果已经处理过了,则跳过
        2. 如果是PriorityOrdered的子类,则添加到priorityOrderedPostProcessors中
        3. 如果是Ordered的子类,则添加到orderedPostProcessorNames中
        4. 如果都不符合,则加入到nonOrderedPostProcessorNames
      4. 对添加到PriorityOrdered中的BeanFactoryPostProcessors 排序后调用invokeBeanFactoryPostProcessors进行处理
      5. 对添加到orderedPostProcessorNames中的name,从beanFactory中获取相应的实例后,添加到orderedPostProcessors,排序后调用invokeBeanFactoryPostProcessors进行处理
      6. 对添加到nonOrderedPostProcessorNames中的name,从beanFactory中获取相应的实例后,添加到nonOrderedPostProcessors,排序后调用invokeBeanFactoryPostProcessors进行处理
      7. 清空beanFactory中的Metadata的缓存.代码如下:

        public void clearMetadataCache() {
            super.clearMetadataCache();
            clearByTypeCache();
        }

      由于此时传入beanFactory是BeanDefinitionRegistry 的子类,因此为执行1.1 .同时传入的beanFactoryPostProcessors有如下3个:

      ConfigurationWarningsApplicationContextInitializer,
      SharedMetadataReaderFactoryContextInitializer,
      PropertySourceOrderingPostProcessor
      

      由于ConfigurationWarningsApplicationContextInitializer是BeanDefinitionRegistryPostProcessor的子类,因此会调用其postProcessBeanDefinitionRegistry,然后添加到registryProcessors中,其实现如下:

      public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
                  throws BeansException {
              for (Check check : this.checks) {
                  String message = check.getWarning(registry);
                  if (StringUtils.hasLength(message)) {
                      warn(message);
                  }
              }
      
          }

      通过遍历其Check,进行检查,如果存在警告,则打印警告日志.
      对于当前场景来说,checks 只有一个ComponentScanPackageCheck.因此为执行如下方法:

          public String getWarning(BeanDefinitionRegistry registry) {
              Set<String> scannedPackages = getComponentScanningPackages(registry);
              List<String> problematicPackages = getProblematicPackages(scannedPackages);
              if (problematicPackages.isEmpty()) {
                  return null;
              }
              return "Your ApplicationContext is unlikely to "
                      + "start due to a @ComponentScan of "
                      + StringUtils.collectionToDelimitedString(problematicPackages, ", ")
                      + ".";
          }

      SharedMetadataReaderFactoryContextInitializer同样也是BeanDefinitionRegistryPostProcessor的子类,因此会加入到registryPostProcessors中.其实现如下:

      public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
                  throws BeansException {
              register(registry);
              configureConfigurationClassPostProcessor(registry);
          }

      2件事

      1. 调用register,向registry注册了一个名为 org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory ,class为SharedMetadataReaderFactoryBean 的bean。
      2. 调用configureConfigurationClassPostProcessor,从registry获得org.springframework.context.annotation.internalConfigurationAnnotationProcessor的bean后,向其添加了一个 名为metadataReaderFactory ,对 org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory 的引用.代码如下:

            private void configureConfigurationClassPostProcessor(
                BeanDefinitionRegistry registry) {
            try {
                BeanDefinition definition = registry.getBeanDefinition(
                        AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME);
                definition.getPropertyValues().add("metadataReaderFactory",
                        new RuntimeBeanReference(BEAN_NAME));
            }
            catch (NoSuchBeanDefinitionException ex) {
            }
        }

      PropertySourceOrderingPostProcessor则不是BeanDefinitionRegistryPostProcessor的子类,因此添加到regularPostProcessors中.

      1.1.3 获得的实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessorde bean 有ConfigurationClassPostProcessor,其id为org.springframework.context.annotation.internalConfigurationAnnotationProcessor.在添加到registryProcessors后,会调用其postProcessBeanDefinitionRegistry方法.
      这是一个核心,我们后续文章进行分析.

      1.1.4 获得实现Ordered接口的BeanDefinitionRegistryPostProcessor为0,因此也就不会执行

      1.1.5 中首先获得BeanDefinitionRegistryPostProcessor的beanName,只有org.springframework.context.annotation.internalConfigurationAnnotationProcessor.由于该类已经处理过了–> 也就是ConfigurationClassPostProcessor,因此不会对其处理.

      1.1.6 中registryPostProcessors有ConfigurationWarningsPostProcessor, SharedMetadataReaderFactoryContextInitializer, ConfigurationClassPostProcessor.因此会调用其postProcessBeanFactory进行处理.
      ConfigurationWarningsPostProcessor,SharedMetadataReaderFactoryContextInitializer都是空实现.

      ConfigurationClassPostProcessor#postProcessBeanFactory代码如下:

      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
          int factoryId = System.identityHashCode(beanFactory);
          if (this.factoriesPostProcessed.contains(factoryId)) {
              throw new IllegalStateException(
                      "postProcessBeanFactory already called on this post-processor against " + beanFactory);
          }
          this.factoriesPostProcessed.add(factoryId);
          if (!this.registriesPostProcessed.contains(factoryId)) {
              // BeanDefinitionRegistryPostProcessor hook apparently not supported...
              // Simply call processConfigurationClasses lazily at this point then.
              processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
          }
      
          enhanceConfigurationClasses(beanFactory);
          beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
      }

      5件事

      1. 生成factoryId.
      2. 添加到factoriesPostProcessed中
      3. 如果registriesPostProcessed 不包含factoryId,则意味着没有对其进行处理,则对其进行处理.这里已经对其处理过了,因此不会执行.
      4. 对beanFactory进行增强.代码如下:

        public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
        Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<String, AbstractBeanDefinition>();
        for (String beanName : beanFactory.getBeanDefinitionNames()) {
            BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
            // 1.通过检查BeanDefinition中的configurationClass 是否为full 来进行判断
            if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
                // 1.1 如果beanDef 不是AbstractBeanDefinition的子类,则抛出异常
                if (!(beanDef instanceof AbstractBeanDefinition)) {
                    throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
                            beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
                }
                // 1.2 如果beanFactory中已经有了beanName 定义的bean 并且log 的日志级别为warn的话,则打印日志
                else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
                    logger.warn("Cannot enhance @Configuration bean definition '" + beanName +
                            "' since its singleton instance has been created too early. The typical cause " +
                            "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
                            "return type: Consider declaring such methods as 'static'.");
                }
                // 1.3 加入到configBeanDefs 中
                configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
            }
        }
        // 2. 如果configBeanDefs 为空,直接return
        if (configBeanDefs.isEmpty()) {
            // nothing to enhance -> return immediately
            return;
        }
        ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
        for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
            AbstractBeanDefinition beanDef = entry.getValue();
            // If a @Configuration class gets proxied, always proxy the target class
            // 3.1 设置preserveTargetClass属性为true
            beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
            try {
                // Set enhanced subclass of the user-specified bean class
                Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
                // 3.2 对其进行增强
                Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
                if (configClass != enhancedClass) {
                    if (logger.isDebugEnabled()) {
                        logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
                                "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
                    }
                    // 3.3 如果增强成功的话,则设置BeanClass为增强后的Class 
                    beanDef.setBeanClass(enhancedClass);
                }
            }
            catch (Throwable ex) {
                throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
            }
        }
        }
        1. 通过遍历beanFactory中注册的beanName.如果BeanDefinition中的configurationClass 为full.

          1. 如果beanDef 不是AbstractBeanDefinition的子类,则抛出异常
          2. 如果beanFactory中已经有了beanName 定义的bean 并且log 的日志级别为warn的话,则打印日志
          3. 添加到configBeanDefs中.
        2. 如果configBeanDefs 为空,直接return
        3. 遍历configBeanDefs,设置preserveTargetClass属性为true.调用ConfigurationClassEnhancer#enhance 对其进行增强,如果增强成功的话,则设置BeanClass为增强后的Class.
      5. 添加一个BeanPostProcessor–>ImportAwareBeanPostProcessor

      1.1.6 中regularPostProcessors 只有一个PropertySourceOrderingPostProcessor,其postProcessBeanFactory代码如下:

      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
                  throws BeansException {
              reorderSources(this.context.getEnvironment());
          }

      调用

      private void reorderSources(ConfigurableEnvironment environment) {
              ConfigurationPropertySources
                      .finishAndRelocate(environment.getPropertySources());
              PropertySource<?> defaultProperties = environment.getPropertySources()
                      .remove(DEFAULT_PROPERTIES);
              if (defaultProperties != null) {
                  environment.getPropertySources().addLast(defaultProperties);
              }
          }

      2件事:

      1. 从environment中的PropertySources 删除applicationConfigurationProperties
      2. 从PropertySources删除defaultProperties,如果删除成功的话,就添加到environment的最后.对于当前来说,PropertySources是不存在defaultProperties的

      我们回到PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors中的第2步,从beanFactory中获得BeanFactoryPostProcessor的name如下:

      org.springframework.context.annotation.internalConfigurationAnnotationProcessor,
      propertySourcesPlaceholderConfigurer, 
      org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.store, 
      preserveErrorControllerTargetClassPostProcessor

      其中实现了PriorityOrdered接口的有PropertySourcesPlaceholderConfigurer,因此会调用其postProcessBeanFactory方法,代码如下:

      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
          if (this.propertySources == null) {
              this.propertySources = new MutablePropertySources();
              if (this.environment != null) {
                  this.propertySources.addLast(
                      new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
                          @Override
                          public String getProperty(String key) {
                              return this.source.getProperty(key);
                          }
                      }
                  );
              }
              try {
                  PropertySource<?> localPropertySource =
                          new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
                  if (this.localOverride) {
                      this.propertySources.addFirst(localPropertySource);
                  }
                  else {
                      this.propertySources.addLast(localPropertySource);
                  }
              }
              catch (IOException ex) {
                  throw new BeanInitializationException("Could not load properties", ex);
              }
          }
      
          processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
          this.appliedPropertySources = this.propertySources;
      }

      3件事

      1. 如果propertySources为null的话,就实例化MutablePropertySources,如果environment 不为null的话,就向propertySources添加一个 名为 environmentProperties 的 PropertySource,实例化 name 为 localProperties 的PropertiesPropertySource
      2. 调用processProperties 处理Placeholder. 代码如下:

        protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
            final ConfigurablePropertyResolver propertyResolver) throws BeansException {
        
        // 1. 设置propertyResolver的属性
        // 设置Placeholder 前缀为 ${
        propertyResolver.setPlaceholderPrefix(this.placeholderPrefix);
        // 设置Placeholder 后缀为 }
        propertyResolver.setPlaceholderSuffix(this.placeholderSuffix);
        // 设置 ValueSeparator 为 :
        propertyResolver.setValueSeparator(this.valueSeparator);
        
        
        // 2. 实例化StringValueResolver
        StringValueResolver valueResolver = new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                String resolved = (ignoreUnresolvablePlaceholders ?
                        propertyResolver.resolvePlaceholders(strVal) :
                        propertyResolver.resolveRequiredPlaceholders(strVal));
                if (trimValues) {
                    resolved = resolved.trim();
                }
                return (resolved.equals(nullValue) ? null : resolved);
            }
        };
        
        // 3. 进行处理
        doProcessProperties(beanFactoryToProcess, valueResolver);
        }

        3件事

        1. 设置propertyResolver的属性,设置Placeholder 前缀为 ${,设置Placeholder 后缀为 },设置 ValueSeparator 为 :
        2. 实例化StringValueResolver
        3. 调用doProcessProperties进行处理.代码如下:

          protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
          StringValueResolver valueResolver) {
          // 1. 实例化BeanDefinitionVisitor
          BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
          // 2. 获得beanFactoryToProcess中的BeanDefinitionNames
          String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
          for (String curName : beanNames) {
          // Check that we're not parsing our own bean definition,
          // to avoid failing on unresolvable placeholders in properties file locations.
          if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
              // 3. 如果curName 不等于当前的beanName,并且beanFactoryToProcess 等于this.beanFactory的话,获得对应的
              // BeanDefinition
              BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
              try {
                  // 4. visitBeanDefinition
                  visitor.visitBeanDefinition(bd);
              }
              catch (Exception ex) {
                  throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, ex.getMessage(), ex);
              }
          }
          }
          // New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
          // 5. 对于别名的处理
          beanFactoryToProcess.resolveAliases(valueResolver);
          // New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
          // 6. 对于嵌套的处理
          beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
          }

          6件事:

          1. 实例化BeanDefinitionVisitor
          2. 获得beanFactoryToProcess中的BeanDefinitionNames
          3. 遍历BeanDefinitionNames,如果curName 不等于当前的beanName,并且beanFactoryToProcess 等于this.beanFactory的话,获得对应的BeanDefinition,然后调用BeanDefinitionVisitor#visitBeanDefinition进行处理.
          4. 对于别名的处理
          5. 对于嵌套的处理,向embeddedValueResolvers添加了StringValueResolver.
      3. 将appliedPropertySources赋值为propertySources.

      第5步,实现了Ordered接口的BeanFactoryPostProcessor没有.
      第6步,nonOrderedPostProcessors的BeanFactoryPostProcessor有

      org.springframework.boot.context.properties.ConfigurationBeanFactoryMetaData
      org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor   
      

      其中ConfigurationBeanFactoryMetaData#postProcessBeanFactory实现如下:

      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
              throws BeansException {
          this.beanFactory = beanFactory;
          for (String name : beanFactory.getBeanDefinitionNames()) {
              BeanDefinition definition = beanFactory.getBeanDefinition(name);
              String method = definition.getFactoryMethodName();
              String bean = definition.getFactoryBeanName();
              if (method != null && bean != null) {
                  this.beans.put(name, new MetaData(bean, method));
              }
          }
      }

      遍历beanFactory中的BeanDefinitionNames,获得相应的BeanDefinition,如果FactoryMethodName,FactoryBeanName 都有配置的话,就添加到beans 中.

      ErrorControllerTargetClassPostProcessor#postProcessBeanFactory,代码如下:

      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
                  throws BeansException {
              String[] errorControllerBeans = beanFactory
                      .getBeanNamesForType(ErrorController.class, false, false);
              for (String errorControllerBean : errorControllerBeans) {
                  try {
                      beanFactory.getBeanDefinition(errorControllerBean).setAttribute(
                              AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
                  }
                  catch (Throwable ex) {
                      // Ignore
                  }
              }
          }

      从beanFactory 获得ErrorController的实例,设置preserveTargetClass 为true.这里默认只有一个,为basicErrorController

    6. 注册拦截bean创建的bean处理器,这里只是注册,真正的调用是在getBean的时候.代码如下:

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

      调用

      public static void registerBeanPostProcessors(
          ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
      
      String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
      
      // Register BeanPostProcessorChecker that logs an info message when
      // a bean is created during BeanPostProcessor instantiation, i.e. when
      // a bean is not eligible for getting processed by all BeanPostProcessors.
      int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
      beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
      
      // Separate between BeanPostProcessors that implement PriorityOrdered,
      // Ordered, and the rest.
      List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
      List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
      List<String> orderedPostProcessorNames = new ArrayList<String>();
      List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
      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);
          }
      }
      
      // First, register the BeanPostProcessors that implement PriorityOrdered.
      sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
      registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
      
      // Next, register the BeanPostProcessors that implement Ordered.
      List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
      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);
      
      // Now, register all regular BeanPostProcessors.
      List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
      for (String ppName : nonOrderedPostProcessorNames) {
          BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
          nonOrderedPostProcessors.add(pp);
          if (pp instanceof MergedBeanDefinitionPostProcessor) {
              internalPostProcessors.add(pp);
          }
      }
      registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
      
      // Finally, re-register all internal BeanPostProcessors.
      sortPostProcessors(internalPostProcessors, beanFactory);
      registerBeanPostProcessors(beanFactory, internalPostProcessors);
      
      // Re-register post-processor for detecting inner beans as ApplicationListeners,
      // moving it to the end of the processor chain (for picking up proxies etc).
      beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
      }
      1. 获得BeanPostProcessor类型的postProcessorNames.如下:

        org.springframework.context.annotation.internalAutowiredAnnotationProcessor, 
        org.springframework.context.annotation.internalRequiredAnnotationProcessor, 
        org.springframework.context.annotation.internalCommonAnnotationProcessor, 
        org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor, 
        embeddedServletContainerCustomizerBeanPostProcessor, 
        errorPageRegistrarBeanPostProcessor, 
        methodValidationPostProcessor

        一共7个

      2. 添加一个BeanPostProcessor–>BeanPostProcessorChecker.BeanPostProcessorChecker是一个普通的信息打印,可能会有些情况,当spring的配置中的后处理器还没有被注册就已经开始了bean的初始化时便会打印出BeanPostProcessorChecker设定的信息.
      3. 遍历postProcessorNames,

        1. 如果该postProcessor实现了PriorityOrdered,则加入priorityOrderedPostProcessors中
        2. 如果postProcessor实现了PriorityOrdered和MergedBeanDefinitionPostProcessor,则加入到internalPostProcessors
        3. 如果postProcessor实现了Ordered,则加入到orderedPostProcessorNames中.
        4. 否则加入到nonOrderedPostProcessorNames.
      4. 注册所有实现PriorityOrdered的BeanPostProcessor.如下:

        org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor, 
        org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor,
        org.springframework.context.annotation.CommonAnnotationBeanPostProcessor, 
        org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor
      5. 注册所有实现Ordered的BeanPostProcessor.如下:

        methodValidationPostProcessor
      6. 注册所有无序的BeanPostProcessor.如下:

        embeddedServletContainerCustomizerBeanPostProcessor,
        errorPageRegistrarBeanPostProcessor
      7. 注册所有MergedBeanDefinitionPostProcessor类型的BeanPostProcessor,并非是重复注册.如下:

        org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor, 
        org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor,
        org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
      8. 添加ApplicationListenerDetector–>ApplicationListenerDetector.
    7. 为上下文初始化MessageSource,即国际化处理,执行如下代码:

      protected void initApplicationEventMulticaster() {
      ConfigurableListableBeanFactory beanFactory = getBeanFactory();
      if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
          this.applicationEventMulticaster =
                  beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
          if (logger.isDebugEnabled()) {
              logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
          }
      }
      else {
          this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
          beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
          if (logger.isDebugEnabled()) {
              logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                      APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                      "': using default [" + this.applicationEventMulticaster + "]");
          }
      }
      }
      1. 如果在配置文件中已经配置了messageSource,那么将messageSource提取并记录在this.messageSource中.

        1. 如果存在父容器,并且messageSource 是HierarchicalMessageSource 的实例,且hms的ParentMessageSource 为null,则调用getInternalParentMessageSource 进行设置.
      2. 如果不存在,则实例化DelegatingMessageSource以便作为getMessage的调用.

        1. 调用getInternalParentMessageSource 进行设置ParentMessageSource
        2. 向beanFactory注册messageSource
    8. 初始化ApplicationEventMulticaster 代码如下:

      protected void initApplicationEventMulticaster() {
      ConfigurableListableBeanFactory beanFactory = getBeanFactory();
      if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
          this.applicationEventMulticaster =
                  beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
          if (logger.isDebugEnabled()) {
              logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
          }
      }
      else {
          this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
          beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
          if (logger.isDebugEnabled()) {
              logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                      APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                      "': using default [" + this.applicationEventMulticaster + "]");
          }
      }
      }
      1. 如果用户自定义了事件广播器,那么就使用用户自定义的事件广播器
      2. 如果没有自定义事件广播器,那么就使用默认的SimpleApplicationEventMulticaster,并向beanFactory 进行注册,id 为applicationEventMulticaster.
    9. 扩展点,onRefresh,留个子类来初始化其他的bean.执行EmbeddedWebApplicationContext#onRefresh,代码如下:

      protected void onRefresh() {
      super.onRefresh();
      try {
          createEmbeddedServletContainer();
      }
      catch (Throwable ex) {
          throw new ApplicationContextException("Unable to start embedded container",
                  ex);
      }
      }
      1. 调用父类的onRefresh.代码如下:

        public static ThemeSource initThemeSource(ApplicationContext context) {
        if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) {
        ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class);
        // Make ThemeSource aware of parent ThemeSource.
        if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) {
            HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource;
            if (hts.getParentThemeSource() == null) {
                // Only set parent context as parent ThemeSource if no parent ThemeSource
                // registered already.
                hts.setParentThemeSource((ThemeSource) context.getParent());
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Using ThemeSource [" + themeSource + "]");
        }
        return themeSource;
        }
        else {
        // Use default ThemeSource to be able to accept getTheme calls, either
        // delegating to parent context's default or to local ResourceBundleThemeSource.
        HierarchicalThemeSource themeSource = null;
        if (context.getParent() instanceof ThemeSource) {
            themeSource = new DelegatingThemeSource();
            themeSource.setParentThemeSource((ThemeSource) context.getParent());
        }
        else {
            themeSource = new ResourceBundleThemeSource();
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME +
                    "': using default [" + themeSource + "]");
        }
        return themeSource;
        }
        }
        1. 如果context中有themeSource的定义

          1. 从context 获取,id 为themeSource type为ThemeSource 的 bean
          2. 如果父容器实现了ThemeSource,并且ThemeSource 是HierarchicalThemeSource 的子类,并且HierarchicalThemeSource 的ParentThemeSource 没有进行设置.则将父容器赋值给HierarchicalThemeSource的ParentThemeSource
        2. 如果context中没有themeSource的定义

          1. 如果父容器为ThemeSource的子类,则实例化DelegatingThemeSource,并将父容器赋值给DelegatingThemeSource的ParentThemeSource
          2. 否则实例化为DelegatingThemeSource
      2. 创建一个嵌入的Servlet容器.这个我们后续分析.

    10. 在所有注册的bean中查找listener beans,注册到消息广播器中.代码如下:

      protected void registerListeners() {
      // Register statically specified listeners first.
      for (ApplicationListener<?> listener : getApplicationListeners()) {
          getApplicationEventMulticaster().addApplicationListener(listener);
      }
      
      // Do not initialize FactoryBeans here: We need to leave all regular beans
      // uninitialized to let post-processors apply to them!
      String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
      for (String listenerBeanName : listenerBeanNames) {
          getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
      }
      
      // Publish early application events now that we finally have a multicaster...
      Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
      this.earlyApplicationEvents = null;
      if (earlyEventsToProcess != null) {
          for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
              getApplicationEventMulticaster().multicastEvent(earlyEvent);
          }
      }
      }
      1. 将硬编码方式注册的监听器添加到SimpleApplicationEventMulticaster中的defaultRetriever的applicationListeners.如下:

        org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer, 
        org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer$AutoConfigurationReportListener, 
        org.springframework.boot.context.config.ConfigFileApplicationListener, 
        org.springframework.boot.context.config.AnsiOutputApplicationListener, 
        org.springframework.boot.logging.LoggingApplicationListener,
        org.springframework.boot.logging.ClasspathLoggingApplicationListener, 
        org.springframework.boot.autoconfigure.BackgroundPreinitializer, 
        org.springframework.boot.context.config.DelegatingApplicationListener,
        org.springframework.boot.builder.ParentContextCloserApplicationListener, 
        org.springframework.boot.ClearCachesApplicationListener 
        org.springframework.boot.context.FileEncodingApplicationListener, 
        org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener,
        org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean, 
        org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor
      2. 将配置文件注册的监听器添加到SimpleApplicationEventMulticaster中的defaultRetriever的applicationListenerBeans. 如下:

        &org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory,
        org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor,
        mvcResourceUrlProvider,
        springApplicationAdminRegistrar]
      3. 将之前发生的ApplicationEvent进行发送. 对于当前场景来说,没有
    11. 初始化剩下的单例(non-lazy-init).代码如下:

      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(new StringValueResolver() {
              @Override
              public String resolveStringValue(String strVal) {
                  return 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();
      
      // Instantiate all remaining (non-lazy-init) singletons.
      beanFactory.preInstantiateSingletons();
      }
      1. 如果beanFactory有id 为 conversionService 并且 type 为 ConversionService 的bean,对beanFactory的ConversionService进行赋值
      2. 如果beanFactory 没有 EmbeddedValueResolver,则添加一个
      3. 初始化type 为 LoadTimeWeaverAware 的 bean.对于当前场景是没有的.
      4. 设置TempClassLoader 为null
      5. 冻结所有的bean的定义,说明注册的bean定义将不被修改或进一步的处理
      6. 初始化剩下的单实例. 未进行解析
    12. 完成刷新过程,执行的是EmbeddedWebApplicationContext#finishRefresh,代码如下:

      protected void finishRefresh() {
      super.finishRefresh();
      EmbeddedServletContainer localContainer = startEmbeddedServletContainer();
      if (localContainer != null) {
          // 发布EmbeddedServletContainerInitializedEvent事件
          publishEvent(
                  new EmbeddedServletContainerInitializedEvent(this, localContainer));
      }
      }
      1. 调用父类的AbstractApplicationContext#finishRefresh.代码如下:

        protected void finishRefresh() {
            // Initialize lifecycle processor for this context.
            initLifecycleProcessor();
            // Propagate refresh to lifecycle processor first.
            getLifecycleProcessor().onRefresh();
            // Publish the final event.
            publishEvent(new ContextRefreshedEvent(this));
            // Participate in LiveBeansView MBean, if active.
            LiveBeansView.registerApplicationContext(this);
        }
        1. 初始化LifecycleProcessor.代码如下:

          protected void initLifecycleProcessor() {
          ConfigurableListableBeanFactory beanFactory = getBeanFactory();
          if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
          this.lifecycleProcessor =
              beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
          if (logger.isDebugEnabled()) {
          logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
          }
          }
          else {
          DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
          defaultProcessor.setBeanFactory(beanFactory);
          this.lifecycleProcessor = defaultProcessor;
          beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
          if (logger.isDebugEnabled()) {
          logger.debug("Unable to locate LifecycleProcessor with name '" +
                  LIFECYCLE_PROCESSOR_BEAN_NAME +
                  "': using default [" + this.lifecycleProcessor + "]");
          }
          }
          }
          1. 如果beanFactory 有 id 为 lifecycleProcessor 且type 为 LifecycleProcessor bean 的话,就将lifecycleProcessor进行赋值
          2. 否则 实例化 DefaultLifecycleProcessor,并向beanFactory 进行注册
        2. 调用lifecycle processor 的onRefresh方法.代码如下:

          public void onRefresh() {
          startBeans(true);
          this.running = true;
          }
          1. 启动Lifecycle类型的bean. 当前环境下 没有.
          2. 将running设置为true.
        3. 发布ContextRefreshedEvent 事件.代码如下:

          protected void publishEvent(Object event, ResolvableType eventType) {
          Assert.notNull(event, "Event must not be null");
          if (logger.isTraceEnabled()) {
          logger.trace("Publishing event in " + getDisplayName() + ": " + event);
          }
          // Decorate event as an ApplicationEvent if necessary
          ApplicationEvent applicationEvent;
          if (event instanceof ApplicationEvent) {
          applicationEvent = (ApplicationEvent) event;
          }
          else {
          applicationEvent = new PayloadApplicationEvent<Object>(this, event);
          if (eventType == null) {
          eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
          }
          }
          // Multicast right now if possible - or lazily once the multicaster is initialized
          if (this.earlyApplicationEvents != null) {
          this.earlyApplicationEvents.add(applicationEvent);
          }
          else {
          getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
          }
          // Publish event via parent context as well...
          if (this.parent != null) {
          if (this.parent instanceof AbstractApplicationContext) {
          ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
          }
          else {
          this.parent.publishEvent(event);
          }
          }
          }
          1. 如果applicationEvent 不是ApplicationEvent 子类的话,就包装为PayloadApplicationEvent. 对于当前的 ContextRefreshedEvent,是ApplicationEvent的子类
          2. 如果earlyApplicationEvents 不等于null,就添加到earlyApplicationEvents中,否则直接进行发布.对于当前场景来说,会调用SimpleApplicationEventMulticaster#multicastEvent直接发布.这里我们之前有分析过,对ContextRefreshedEvent类型的事件感兴趣的Listener有:

            org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor,
            org.springframework.boot.context.config.DelegatingApplicationListener,
            org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer$AutoConfigurationReportListener,
            org.springframework.boot.ClearCachesApplicationListener,
            org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean,
            org.springframework.web.servlet.resource.ResourceUrlProvider

            ConfigurationPropertiesBindingPostProcessor最终会调用freeLocalValidator,代码如下:

            private void freeLocalValidator() {
            try {
            Validator validator = this.localValidator;
            this.localValidator = null;
            if (validator != null) {
            ((DisposableBean) validator).destroy();
            }
            }
            catch (Exception ex) {
            throw new IllegalStateException(ex);
            }
            }

            调用Validator的destroy 进行销毁.

            DelegatingApplicationListeners没有做处理.
            AutoConfigurationReportListener最终会执行AutoConfigurationReportLoggingInitializer#logAutoConfigurationReport,代码如下:

            private void logAutoConfigurationReport() {
            logAutoConfigurationReport(!this.applicationContext.isActive());
            }

            调用

            public void logAutoConfigurationReport(boolean isCrashReport) {
            if (this.report == null) {
            if (this.applicationContext == null) {
            this.logger.info("Unable to provide auto-configuration report "
                + "due to missing ApplicationContext");
            return;
            }
            this.report = ConditionEvaluationReport
            .get(this.applicationContext.getBeanFactory());
            }
            if (!this.report.getConditionAndOutcomesBySource().isEmpty()) {
            if (isCrashReport && this.logger.isInfoEnabled()
            && !this.logger.isDebugEnabled()) {
            this.logger.info(String
                .format("%n%nError starting ApplicationContext. To display the "
                        + "auto-configuration report re-run your application with "
                        + "'debug' enabled."));
            }
            if (this.logger.isDebugEnabled()) {
            this.logger.debug(new ConditionEvaluationReportMessage(this.report));
            }
            }
            }

            ClearCachesApplicationListener#onApplicationEvent,代码如下:

            public void onApplicationEvent(ContextRefreshedEvent event) {
            ReflectionUtils.clearCache();
            clearClassLoaderCaches(Thread.currentThread().getContextClassLoader());
            }
            1. 清除ReflectionUtils的缓存.代码如下:

              public static void clearCache() {
                  declaredMethodsCache.clear();
                  declaredFieldsCache.clear();
              }
            2. 递归清除ClassLoader的缓存.代码如下:

              private void clearClassLoaderCaches(ClassLoader classLoader) {
              if (classLoader == null) {
              return;
              }
              try {
              Method clearCacheMethod = classLoader.getClass()
              .getDeclaredMethod("clearCache");
              clearCacheMethod.invoke(classLoader);
              }
              catch (Exception ex) {
              // Ignore
              }
              clearClassLoaderCaches(classLoader.getParent());
              }

            SharedMetadataReaderFactoryBean#onApplicationEvent ,清空了metadataReaderFactory的缓存,代码如下:

            public void onApplicationEvent(ContextRefreshedEvent event) {
            this.metadataReaderFactory.clearCache();
            }

            调用

            public void clearCache() {
                    this.cache.clear();
            }

            ResourceUrlProvider#onApplicationEvent,代码如下:

            public void onApplicationEvent(ContextRefreshedEvent event) {
            if (isAutodetect()) {
            this.handlerMap.clear();
            detectResourceHandlers(event.getApplicationContext());
            if (this.handlerMap.isEmpty() && logger.isDebugEnabled()) {
            logger.debug("No resource handling mappings found");
            }
            if (!this.handlerMap.isEmpty()) {
            this.autodetect = false;
            }
            }
            }
            
            1. 如果autodetect为true的话.

              1. 清空handlerMap
              2. 调用detectResourceHandlers,将SimpleUrlHandlerMapping中handler为ResourceHttpRequestHandler的添加到handlerMap中.对于当前环境, handlerMap为:

                /**/favicon.ico=ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@6bbe50c9]], 
                /webjars/**=ResourceHttpRequestHandler [locations=[class path resource [META-INF/resources/webjars/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@3c46dcbe]], 
                /**=ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@68577ba8]]
              3. 如果handlerMap 不为空,则将autodetect设为false.
            2. 直接return
          3. 如果有父容器的话,
            1. 如果父容器是AbstractApplicationContext 实例化,向父容器发布事件
            2. 否则直接进行发布
        4. 向LiveBeansView进行注册.
      2. 启动嵌入的ServletContainer , 这里我们后续分析
      3. 如果启动成功的话,发布EmbeddedServletContainerInitializedEvent事件,这里我们后续分析
    13. 清除缓存.代码如下:

      protected void resetCommonCaches() {
      ReflectionUtils.clearCache();
      ResolvableType.clearCache();
      CachedIntrospectionResults.clearClassLoader(getClassLoader());
      }
      1. 清除ReflectionUtils的缓存,这个我们已经分析过了
      2. 清除ResolvableType的缓存
      3. 清除CachedIntrospectionResults中的缓存

    至此我们就分析完了.

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/qq_26000415/article/details/78915221
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞