全面开战系列之Spring源码---IOC实例化前的准备工作(三)

文章目录

  • 系列文章目录
  • 前言
  • 一、配置BeanFactory
  • 二、动态注册bean到容器
  • 三、注册BeanPostProcessor
  • 四、总结

系列文章目录

  •  全面开战系列之Spring源码---Spring概述(一)
  • 全面开战系列之Spring源码---IOC启动流程(二)

  • 全面开战系列之Spring源码---Bean实例化流程(四)

 

前言

在上一节IOC启动流程中,已经分析了加载bean过程,此时距离真正实例化bean步骤还有一段距离。本节主要分析从bean定义到bean实例化之间Spring会做什么。

Spring的一个明显特性是:可扩展性强,允许使用者参与Ioc创建过程。

回顾IOC的创建过程(refresh方法):

AbstractApplicationContext
    @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.
         //这个方法负责了BeanFactory的初始化、Bean的加载和注册等事件
         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.
            //Spring的一个扩展点
            /**
             * 如果有Bean实现了BeanFactoryPostProcessor接口,
             * 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。
             * 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
             */
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            //调用BeanFactoryPostProcessor各个实现类的postProcessBeanFactory(factory) 方法
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            //注册 BeanPostProcessor 的实现类,注意不是BeanFactoryPostProcessor
            //此接口有两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
            // 分别会在Bean初始化之前和初始化之后得到执行
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            //初始化当前 ApplicationContext 的 MessageSource,有想了解国际化的相关知识可以深入研究一下
            initMessageSource();

            // Initialize event multicaster for this context.
            //这个方法主要为初始化当前 ApplicationContext 的事件广播器
            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.
            //负责初始化所有的没有设置懒加载的singleton bean
            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.
            //销毁已创建的 Bean
            destroyBeans();

            // Reset 'active' flag.
            //取消 refresh 操作,重置容器的同步标识.
            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();
         }
      }
   }

本节主要关注 prepareBeanFactory(beanFactory), 

                      invokeBeanFactoryPostProcessors(beanFactory);

            registerBeanPostProcessors(beanFactory); 

这三个方法。

一、配置BeanFactory

prepareBeanFactory这个方法主要是对BeanFactory做一些配置,设置一些必要的类

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
   // 设置为加载当前ApplicationContext类的类加载器
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
   // 这里是Spring的又一个扩展点
   //在所有实现了Aware接口的bean在初始化的时候,这个 processor负责回调,
   // 这个我们很常用,如我们会为了获取 ApplicationContext 而 implement ApplicationContextAware
   // 注意:它不仅仅回调 ApplicationContextAware,还会负责回调 EnvironmentAware、ResourceLoaderAware 等
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   // 如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们,Spring 会通过其他方式来处理这些依赖。
   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.
   //下面几行就是为特殊的几个 bean 赋值,如果有 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.
   // 如果存在bean名称为loadTimeWeaver的bean则注册一个BeanPostProcessor
   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.
   // 如果没有定义 "environment" 这个 bean,那么 Spring 会 "手动" 注册一个
   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());
   }
}

二、动态注册bean到容器

Spring提供 BeanDefinitionRegistryPostProcessor 这个接口来实现动态注册bean

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

   /**
    * Modify the application context's internal bean definition registry after its
    * standard initialization. All regular bean definitions will have been loaded,
    * but no beans will have been instantiated yet. This allows for adding further(更多的)
    * bean definitions before the next post-processing phase kicks in.
    * @param registry the bean definition registry used by the application context
    * @throws org.springframework.beans.BeansException in case of errors
    */
   void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

可以看到,传入了一个BeanDefinitionRegistry,这个接口有那些方法?

全面开战系列之Spring源码---IOC实例化前的准备工作(三)_第1张图片

可以通过这个接口,实现向BeanFactory添加,移除,获取BeanDefinition等操作,从而实现动态添加Bean

IOC容器启动时,会去遍历Bean定义列表,实现BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry()方法。

再仔细分析BeanDefinitionRegistryPostProcessor接口,它还继承了BeanFactoryPostProcessor这个接口

@FunctionalInterface
public interface BeanFactoryPostProcessor {

   /**
    * Modify the application context's internal bean factory after its standard
    * initialization. All bean definitions will have been loaded, but no beans
    * will have been instantiated yet. This allows for overriding or adding
    * properties even to eager-initializing beans.
    * @param beanFactory the bean factory used by the application context
    * @throws org.springframework.beans.BeansException in case of errors
    */
   void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

在postProcessBeanFactory方法中,传入了ConfigurableListableBeanFactory,也就是beanFactory

看看ConfigurableListableBeanFactory的继承结构

全面开战系列之Spring源码---IOC实例化前的准备工作(三)_第2张图片

只要是这个在这个继承结构体系里的所有方法都可以使用。通常BeanFactoryPostProcessor用来获取BeanDefinition,然后对bean

属性值进行修改。

接下来看看spring是如何回调这些接口的

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

PostProcessorRegistrationDelegate

/**
 * 1.处理 实现过BeanDefinitionRegistryPostProcessor接口,由于该接口同时实现了BeanFactoryPostProcessor接口,
 *   所以需要分别调用各自的回调方法(postProcessBeanDefinitionRegistry,postProcessBeanFactory)
 * 2.处理实现了BeanFactoryPostProcessor接口的bean
 * @param beanFactory
 * @param beanFactoryPostProcessors
 */
public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
   //将所有已经执行过接口方法的bean放入其中,防止重复执行
   Set processedBeans = new HashSet<>();
   //处理针对beanFactory这一级别
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List regularPostProcessors = new ArrayList<>();
      List registryProcessors = new ArrayList<>();

      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 currentRegistryProcessors = new ArrayList<>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      //从容器中获取实现过BeanDefinitionRegistryPostProcessor接口的bean
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            //beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)会先实例化 ppName对应的bean,
            // 方便之后ppName回调BeanDefinitionRegistryPostProcessor的接口方法
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      //执行BeanDefinitionRegistryPostProcessor 的postProcessBeanDefinitionRegistry方法
      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);
      //执行postProcessBeanDefinitionRegistry 方法
      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.
      //最后,所有的bean都执行BeanFactoryPostProcessor 的postProcessBeanFactory方法
      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!
   //这一步获取容器中bean有实现 BeanFactoryPostProcessor 接口的bean(针对bean)
   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)) {
         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 orderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   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));
   }
   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();
}

由于考虑到执行先后问题,spring提供了 PriorityOrdered, Ordered 接口决定优先级。

PriorityOrdered优先级  > Ordered 优先级 > 普通

 

三、注册BeanPostProcessor

BeanPostProcessor是Spring提供的又一扩展点,看看接口结构

public interface BeanPostProcessor {

   @Nullable
   default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

   @Nullable
   default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
   }

}

就2个方法,before,after 见名知意。此时传入的bean已经是实例化的bena了

 

该方法具体调用是在实例化过程,而本节分析它具体的注册过程。即让BeanFactory获取n实现了BeanPostProcessor接口的bean,然后注册到容器中。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
PostProcessorRegistrationDelegate
/**
 * 注册容器中所有实现了BeanPostProcessors接口的bean
 * @param beanFactory
 * @param applicationContext
 */
public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
   //获取容器中BeanPostProcessor的实现类
   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 priorityOrderedPostProcessors = new ArrayList<>();
   List internalPostProcessors = new ArrayList<>();
   List orderedPostProcessorNames = new ArrayList<>();
   List nonOrderedPostProcessorNames = new ArrayList<>();
   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 orderedPostProcessors = new ArrayList<>();
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // Now, register all regular BeanPostProcessors.
   List nonOrderedPostProcessors = new ArrayList<>();
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

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

这个接口同样有调用优先级的区分

PriorityOrdered > Ordered > 普通

四、总结

本节内容主要分析了在bean加载完成后,bean实例化之前Spring容器会做的一些准备工作。重点分析了

BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor 这两个接口的回调过程以及 BeanPostProcessors 接口的注册过程,过程相对来说较为清晰。

下一节将分析bean实例化过程

 

你可能感兴趣的:(Spring,java,spring)