Spring源码解析-invokeBeanFactoryPostProcessors

2,119 阅读6分钟

脉络

Spring的源码非常复杂,在看Spring的源码之前,我们先整理一下Spring运转的脉络,这样有助于我们更快地理解Spring

image.png

在解释流程之前,需要明确的一点是,Spring是构建在java语言上的框架,所以它逃脱不了java语言的束缚。

  1. Spring最著名的两个东西是IOC和AOP,什么是IOC,就是控制反转,对象生命周期的管理本来是程序员的工作,现在由Spring帮我们做了,那Spring是如何创建对象的,java创建对象的方式有4种,Spring使用的是反射的方式,图中实例化bean就是使用反射的方式
  2. 在创建对象之前,需要获取对象的属性,Spring中,提供了多种获取属性的方式(xml、annotation、yml、properties),Spring抽象出了BeanDefinitionReader接口,实现此接口可自定义获取属性的方式,读取到对象属性后,会将对象属性包装成一个个BeanDefinition
  3. 获取到BeanDefinition之后,会执行一系列的BeanFactoryPostProcessor,这些BeanFactoryPostProcessor中,有一个非常重要的类,叫ConfigurationClassPostProcessor,后续会讲,同时,这也是Spring的一个扩展点,我们可以定义自己的BeanFactoryPostProcessor,修改BeanDefinition,实现自己的业务扩展
  4. 执行完BeanFactoryPostProcessor之后,就到了bean生命周期阶段,Spring在bean的生命周期中留了非常多的扩展点,实例化前,实例化后,初始化前,初始化后,这些扩展点都是通过一个个BeanPostProcess实现的
  5. Spring中,有两个东西是一直伴随的,分别是Message、Environment,通过Environment可以获取到环境变量,Message事件机制使用了观察者模式,个人认为类似一个Spring内部小型MQ

一些重要的类

image.png

BeanFactory作为最顶层的一个接口类,它定义了IOC容器的基本功能规范,BeanFacotry有三个子类,ListableBeanFactory、HierarchicalBeanFactory和AutowireCapableBeanFactory,但是从上图中我们可以发现最终的默认实现类是DefaultListableBeanFactory,它实现了所有的接口,那为何要定义这么多层次的接口呢?查阅这些接口的源码和说明发现,每个接口都有他使用的场合,它主要是为了区分在Spring内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。例如ListableBeanFactory接口表示这些Bean是可罗列的,而HierarchicalBeanFactory表示的是这些Bean是有继承关系的,也就是每个Bean有可能有父Bean。AutowireCapableBeanFactory接口定义Bean的自动装配规则。这四个接口共同定义了Bean的集合、Bean之间的关系、以及Bean行为

源码解析

refresh()

从最著名的refresh方法开始看

@Override
public void refresh() throws BeansException, IllegalStateException {
  synchronized (this.startupShutdownMonitor) {

      // 此方法完成一些基础的准备工作,例如设置时间,设置启动关闭标志,检查环境变量,并提供子类拓展,
      // 用来将属性注入到ApplicationContext中,设置时间监听器集合
      prepareRefresh();


      // 此方法有以下几个操作:
      // 1.创建DefaultListableBeanFactory。
      // 2.customizeBeanFactory此方法是留给子类实现的,推荐通过override的方式对现有BeanFactory做个性化设
      // 置,allowBeanDefinitionOverriding表示是否允许一个同名的类来覆盖原有类,allowCircularReferences表示是否允许多个类        			 // 之间的循环引用。
      // 3.loadBeanDefinitions表示把所有的bean的定义保存在context,注意是bean的定义
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();


      // 为BeanFactory配置容器特性,例如类加载器,事件处理器等
      prepareBeanFactory(beanFactory);

   try {

      // 像是留给开发者的扩展点,我也不知道具体的作用
      postProcessBeanFactory(beanFactory);

      // 调用所有注册的BeanFactoryPostProcessor的Bean
      invokeBeanFactoryPostProcessors(beanFactory);

      // Register bean processors that intercept bean creation.
      // 注册BeanPostProcessors,流程基本和beanFactoryPostProcessor的初始化是一样的
      registerBeanPostProcessors(beanFactory);

      // Initialize message source for this context.
      // 初始化信息源,和国际化相关
      initMessageSource();

      // Initialize event multicaster for this context.
      // 初始化容器事件传播器
      initApplicationEventMulticaster();

      // Initialize other special beans in specific context subclasses.
      // 在特定上下文子类中初始化其它特殊Bean
      onRefresh();

      // Check for listener beans and register them.
      // 检查监听器Bean并初始化它们
      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();
    }
  }
}
prepareBeanFactory()

这个方法是BeanFactory创建后的准备工作,基本上都是在设置属性

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 设置类加载器
        beanFactory.setBeanClassLoader(getClassLoader());
  	// 设置解析EL表达式的组件
	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // 注册一个BeanPostProcessor,这个是一个非常重要的Processor,后面在bean的生命周期中会讲
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  	// ignoreDependencyInterface表示自动装配时,忽略此接口
  	// 比如 test implements ApplicationContextAware,在test类中想要自动注入			 
        // ApplicationContextAware是无法做到的,但是有工作经验的程序员肯定实现过这个类,发现属性是
  	// 设置成功的,那是因为是ApplicationContextAwareProcessor这个类的回调实现的,并不是自动装配实现的
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

	// registerResolvableDependency,某接口有多个实现类,自动注入时,spring不知道注入哪个类
  	// 使用这个方法可以指定注入的实现类
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));


        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));

                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // 设置environment相关的bean
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
                beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
                beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
                beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
}
invokeBeanFactoryPostProcessors()

image.png

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // 保存所有调用过的PostProcessor的beanName
        Set<String> processedBeans = new HashSet<>();

        if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                // 这两个list主要用来分别收集BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
                List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
                List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                        // 对已注册在DefaultListBeanFactory的BeanFactoryPostProcessor进行分类
                        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                                BeanDefinitionRegistryPostProcessor registryProcessor =
                                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                                // 已注册在DefaultListBeanFactory的BeanDefinitionRegistryPostProcessor优先级最高
                                // 如果postProcessor是BeanDefinitionRegistryPostProcessor的实例
                                // 执行postProcessor的postProcessBeanDefinitionRegistry
                                // 为什么执行完之后还要保存到List中呢?
                                // 因为这里只是执行完了BeanDefinitionRegistryPostProcessor的回调
                                // 父类BeanFactoryPostProcessor的方法还没有进行回调
                                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                                registryProcessors.add(registryProcessor);
                        }
                        else {
                              // 如果不是BeanDefinitionRegistryPostProcessor的实例
                              // 则是BeanFactoryPostProcessor的实例,存放在List中,后面会进行回调
                              regularPostProcessors.add(postProcessor);
                        }
                }

                // 定义了一个集合来存放当前需要执行的BeanDefinitionRegistryPostProcessor
                List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

                // 首先执行实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor
                // 这里只能获取到Spring内部注册的BeanDefinitionRegistryPostProcessor,因为到这里spring还没有去扫描Bean,获取不到我们               			// 通过@Component标志的自定义的BeanDefinitionRegistryPostProcessor
                // 一般默认情况下,这里只有一个beanName,
                // org.springframework.context.annotation.internalConfigurationAnnotationProcessor
                // 对应的BeanClass:ConfigurationClassPostProcessor
                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));
                                // 保存调用过的beanName
                                processedBeans.add(ppName);
                        }
                }
                // 排序
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                // registryProcessors存放的是BeanDefinitionRegistryPostProcessor
                registryProcessors.addAll(currentRegistryProcessors);
                // 执行BeanDefinitionRegistryPostProcessor,一般默认情况下,只有ConfigurationClassPostProcessor
                // ConfigurationClassPostProcessor的具体作用后面再讲,这里先认为它执行完扫描,并且注册BeanDefinition
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                // 清空临时变量,后面再使用
                currentRegistryProcessors.clear();

                // 第二步执行实现了Ordered的BeanDefinitionRegistryPostProcessor
                // 这里为什么要再一次从beanFactory中获取所有的BeanDefinitionRegistryPostProcessor,是因为上面的操作有可能注册了
                // 新的BeanDefinitionRegistryPostProcessor,所以再获取一次
                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));
                                // 保存调用过的beanName
                                processedBeans.add(ppName);
                        }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();


                // 上面两步的套路是一模一样的,唯一不一样的地方是第一步执行的是实现了PriorityOrdered的
                // BeanDefinitionRegistryPostProcessor,第二步是执行的是实现了Ordered的
                // BeanDefinitionRegistryPostProcessor


                // 最后一步,执行没有实现PriorityOrdered或者Ordered的BeanDefinitionRegistryPostProcessor
                // 比较不一样的是,这里有个while循环,是因为在实现BeanDefinitionRegistryPostProcessor的方法的过程中有可能会注册新的
                // BeanDefinitionRegistryPostProcessor,所以需要处理,直到不会出现新的BeanDefinitionRegistryPostProcessor为止
                boolean reiterate = true;
                while (reiterate) {
                        reiterate = false;
                        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                        for (String ppName : postProcessorNames) {
                                if (!processedBeans.contains(ppName)) {
                                        // 发现还有未处理过的BeanDefinitionRegistryPostProcessor,按照套路放进list中
                                        // reiterate标记为true,后面还要再执行一次这个循环,因为执行新的BeanDefinitionRegistryPostProcessor有可能会
                                        // 注册新的BeanDefinitionRegistryPostProcessor
                                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                                        processedBeans.add(ppName);
                                        reiterate = true;
                                }
                        }
                        sortPostProcessors(currentRegistryProcessors, beanFactory);
                        registryProcessors.addAll(currentRegistryProcessors);
                        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                        currentRegistryProcessors.clear();
                }
                // 方法开头前几行分类的两个list就是在这里调用
                // BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
                // 刚刚执行了BeanDefinitionRegistryPostProcessor的方法
                // 现在要执行父类BeanFactoryPostProcessor的方法
                invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
                // Invoke factory processors registered with the context instance.
                invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }


        // 上面BeanFactoryPostProcessor的回调可能又注册了一些类,下面需要再走一遍之前的逻辑
        String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // 根据不同的优先级,分成三类
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
                // 上面处理BeanDefinitionRegistryPostProcessor的时候已经处理过,这里不再重复处理
                // 因为BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
                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.
        // 下面的逻辑跟上面是一致的,先处理实现了PriorityOrdered接口的
        // 再处理实现了Ordered接口的
        // 最后处理普通的BeanFactoryPostProcessor
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        List<BeanFactoryPostProcessor> 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<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        // 因为各种BeanFactoryPostProcessor可能修改了BeanDefinition
        // 所以这里需要清除缓存,需要的时候再通过merge的方式获取
        beanFactory.clearMetadataCache();
}

invokeBeanFactoryPostProcessors这个方法的代码很多,但是逻辑并不复杂。

处理顺序:

  1. 处理入参beanFactoryPostProcessors中的BeanDefinitionRegistryPostProcessor,调用postProcessBeanDefinitionRegistry方法

  2. 处理实现了PriorityOrdered和BeanDefinitionRegistryPostProcessor接口的实现类,调用postProcessBeanDefinitionRegistry方法

  3. 处理实现了Ordered和BeanDefinitionRegistryPostProcessor接口的实现类,调用postProcessBeanDefinitionRegistry方法

  4. 处理既没有实现PriorityOrdered接口也没有实现Ordered接口,但是实现了BeanDefinitionRegistryPostProcessor接口的实现类,调用postProcessBeanDefinitionRegistry方法

  5. 处理所有实现了BeanDefinitionRegistryPostProcessor接口的实现类,调用postProcessBeanFactory

  6. 处理入参beanFactoryPostProcessors中BeanFactoryPostProcessor,调用postProcessBeanFactory

以上是处理BeanDefinitionRegistryPostProcessor接口的实现类,下面开始处理BeanFactoryPostProcessor接口的实现类,处理步骤跟上面是类似的

  1. 先处理实现了PriorityOrdered接口的,再处理实现了Ordered接口的,最后是处理剩下的

测试

测试例子比较寒酸,主要在于说明问题

@Component
public class BeanDefinitionRegistryPostProcessorTest implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("A");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("B");
    }
}

@Component
public class BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("C");
    }
}
@Configuration
@ComponentScan("com.example")
public class Config {
}
public class Test {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(Config.class);
        context.refresh();
        context.close();
    }

}

image.png

参考资料

B站马士兵老师的源码视频