zoukankan      html  css  js  c++  java
  • Spring源码之BeanFactoryPostProcessor的执行顺序

    简介

    BeanFactoryPostProcessor 是 Factory hook,行话“钩子”。这个类允许我们对 ApplicationContext 中的 BeanDefinition 自定义修改。

    Spring 中有两个比较重要的拓展点,一个是 BeanFactoryPostProcessor,另一个是 BeanPostProcessor


    如图所示,BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 的子类。

    探究

    应用上下文类 AnnotationConfigApplicationContext,实例化方法如下:

    public class MyApplication {
    	public static void main(String[] args) throws IOException {
    		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    	}
    }
    

    配置类 AppConfig 设置扫描包为 coderead.springframework :

    @ComponentScan("coderead.springframework")
    public class AppConfig {
    }
    

    执行 new AnnotationConfigApplicationContext(AppConfig.class) 会触发 refresh() 方法

    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
          this();
          register(componentClasses);
          refresh();
    }
    

    refresh() 方法中有两个重要的方法, invokeBeanFactoryPostProcessors 执行所有的 BeanFactoryPostProcessor, registerBeanPostProcessor 注册 BeanPostProcessor。今天主要研究前者。

    invokeBeanFactoryPostProcessors 顾名思义,触发所有的 BeanFactoryPostProcessor 实现类,当然也包括BeanDefinitionRegistryPostProcessor 的实现类,因为前者是后者的超类。
    新建一个类 A 实现 BeanFactoryPostProcessor:

    @Component
    public class A implements BeanFactoryPostProcessor  {
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    		System.out.println("A ------ BeanFactoryPostProcessor 实现方法");
    	}
    }
    

    再新建一个类 SubX 实现 BeanDefinitionRegistryPostProcessor,Sub 代表这个类继承是子类接口 :

    @Component
    public class SubX implements BeanDefinitionRegistryPostProcessor {
    	@Override
    	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    		System.out.println("SubX ------ BeanDefinitionRegistryPostProcessor 实现方法");
    	}
    
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    		System.out.println("SubX ------ BeanFactoryPostProcessor 实现方法");
    	}
    }
    

    源码阅读

    进入 invokeBeanFactoryPostProcessors,我们首先会迎来第一个 if 判断,判断当前使用的工厂对象是不是 BeanDefinitionRegistry,这个判断 99% 都会返回 true,为什么呢?除非自己继承整个工厂的顶级接口 AliasRegistry 去实现一个完全由自己设计的工厂,这个判断才会走向 else 分支。一般项目根本遇不到这种需求,所以不必深究,因此我们关注 if 分支中的逻辑就好。

    if (beanFactory instanceof BeanDefinitionRegistry) {
          // 通常情况都会进入这块代码段执行,因此这段代码的逻辑才是研究的重点
          // ....
    } else {
          // 除非改写 beanFactory,且不让它实现 BeanDefinitionRegistry,否则都不会执行这段代码
          // 一般来说,这样的改写情况少之又少,少到可以忽略不计
          // ....
    }
    

    然后,我们看到方法中初始化了 2 个集合:

    // 第一个集合存放程序员手动提供给 Spring 的 BeanFactoryPostProcessor,手动代表不是通过扫描注解得到的,而是我们自己添加进去的
    List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    // 存放执行过程中找到的 BeanDefinitionRegistryPostProcessor。
    // 这些被存放的后置处理器有一个共同的特点就是都已经执行过父类接口的 postProcessBeanDefinitionRegistry,而它们被存放在 registryProcessors 集合中的原因是
    // 方便之后会被 invokeBeanFactoryPostProcessors 方法调用,遍历执行子类接口 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
    List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    

    接着我们遇到第一个循环。这个循环是为了循环程序员自己手动添加的后置处理器(添加的方法会后续章节阐述)

    // 遍历程序员手动添加的 BeanFactory 后置处理器
    for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    	if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    // 如果是 BeanDefinitionRegistryPostProcessor,先调用 postProcessBeanDefinitionRegistry 方法,再放入 registryProcessors 集合
    		BeanDefinitionRegistryPostProcessor registryProcessor =
    				(BeanDefinitionRegistryPostProcessor) postProcessor;
    		registryProcessor.postProcessBeanDefinitionRegistry(registry);
    		registryProcessors.add(registryProcessor);
    	}
    	else {
                    // 如果只是 BeanFactoryPostProcessor,那么先放入 regularPostProcessors 集合中,
                    // 等待 BeanDefinitionRegistryPostProcessor 都被找到,都执行完 postProcessBeanDefinitionRegistry 方法和 postProcessBeanFactory 方法
                    // 再执行 regularPostProcessors 集合中的 BeanFactoryPostProcessor.postProcessBeanFactory
    		regularPostProcessors.add(postProcessor);
    	}
    }
    

    紧接着,源码中声明并创建 List currentRegistryProcessors = new ArrayList<>();。 这个集合的作用:

    • 将实现 PriorityOrdered, Ordered 以及剩余的其他 BeanDefinitionRegistryPostProcessor 分离开来
    • 存放通过 beanFactory.getBean 获取并创建的 BeanDefinitionRegistryPostProcessor Bean对象
    • 方便对当前正要执行的一组 BeanDefinitionRegistryPostProcessor 进行必要的排序(比如按照 Ordered 接口的 getOrder 的值,或者按照 beanName 排序)

    然后,ListableBeanFactory.getBeanNamesForType 这个方法返回与给定类型(包括子类)匹配的bean的名称。那么能不能找到呢?答案是肯定的。getBeanNamesForType 方法会从 beanDefinitionMap 中寻找合适的类型,然后返回对应的 beanName。

    上图是当前 beanDefinitionMap 中存放着所有 beaName 及其的对应 BeanDefinition 实例,从中找到了一个符合条件的后置处理器,他的 beanName 是 "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"

    我们从 beanDefintionMap 中用这个 beanName 获取 BeanDefinition 实例,并且通过 getBeanClassName() 方法得到这个 Bean定义所代表的 Java 类是 org.springframework.context.annotation.ConfigurationClassPostProecssor。他是唯一的 Spring 内置 BeanDefinitionRegistryPostProcessor 实例。

    ConfigurationClassPostProecssor 实现 PriorityOrdered 接口,所以会进入 if 内执行代码。

    // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    String[] postProcessorNames =
    		beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
            // ConfigurationClassPostProcessor 实现了 PriorityOrdered 接口,isTypeMatch 返回 true,继续执行
    	if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 执行 getBean 后,会创建 ConfigurationClassPostProcessor 的 Bean 对象,并添加到 beanFactory 的单例池 singletonObjects 中去 
                    // 然后把返回的 Bean 对象放入 currentRegistryProcessors 集合中
    		currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    		processedBeans.add(ppName);
    	}
    }
    // 对当前要执行的 BeanDefinitionPostProcessor 排序(具体的排序代码先不管)
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    // registryProcessors 中存放的是所有 BeanDefinitionRegistryPostProcessor
    registryProcessors.addAll(currentRegistryProcessors);
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
    // 清空当前执行的 BeanDefinitionRegistryPostProcessor
    currentRegistryProcessors.clear();
    

    如下图所示,执行 getBean 之后,DefaultListableBeanFactory 的单例池中新增了一个 ConfigurationClassPostProcessor Bean对象。

    ConfigurationClassPostProcessor 这个类是 Spring 初始化的时候就放置到容器里面的,他做的事情很简单,就是解析 Spring 配置类,然后扫描指定的包路径,将符合条件的类,比如@Component,@Bean注解的类,转换成 BeanDefinition,然后存放到 beanDefinitionMap 中。真正执行这些操作是在被调用 postProcessBeanDefinitionRegistry 方法时。

    我们接着就来说说这个 invokeBeanDefinitionRegistryPostProcessors 方法:

    private static void invokeBeanDefinitionRegistryPostProcessors(
    		Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
            // 遍历传入的 BeanDefinitionRegistryPostProcessor 集合
    	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
    		StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
    				.tag("postProcessor", postProcessor::toString);
                    // 触发 postProcessBeanDefinitionRegistry 方法
    		postProcessor.postProcessBeanDefinitionRegistry(registry);
    		postProcessBeanDefRegistry.end();
    	}
    }
    

    这个方法会遍历 BeanDefinitionRegistryPostProcessor 列表并且执行 postProcessBeanDefinitionRegistry 方法。
    在首次执行时,ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry 方法完成了对项目的扫描,在此之后,Spring容器中有值了,有了我们配置的所有的应该被 Spring 管理的类!比如在本文实验中, A.class 和 SubX.class 被扫描到并转换成 ScannedGenericBeanDefinition 放入了 beanDefinitionMap 中。如下图所示:

    第二段代码基本和上一段的代码一样,唯一不同的地方就是本次寻找的是实现了Ordered 接口的 BeanDefinitionRegistryPostProcessor

    // 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, beanFactory.getApplicationStartup());
    currentRegistryProcessors.clear();
    

    这次执行时,postProcessorNames 可以获得 2 个候选,一个是 Spring 内置的 org.springframework.context.annotation.internalConfigurationAnnotationProcessor,另一个是我们自定义的 subX。如下图所示,beanDefinitionMap 中有 5 个绿色的表示 Spring 内置的 5 个 BeanDefinition,appConfig 是配置类,a 和 subX 是我们自定义的,其中实现 BeanDefinitionRegistryPostProcessor 的只有 2 个。

    processedBeans 集合存放所有已经处理过的 BeanFactoryPostProcessor 及其子类接口 BeanDefinitionRegistyPostProcessor。
    ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry 已经执行过了,所以这一次不会再执行。SubX 因为没有实现 Ordered 接口,所以本次也不会执行。

    接着往下看,开始调用剩余的 BeanDefintionRegistryPostProcessor:

    // 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) {
                    // 与第二次不同,这次不需要实现 Ordered 接口
    		if (!processedBeans.contains(ppName)) {
                            // 获取并创建 BeanDefinitionRegistryPostProcessor Bean对象
    			currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    			processedBeans.add(ppName);
    			reiterate = true;
    		}
    	}
    	sortPostProcessors(currentRegistryProcessors, beanFactory);
    	registryProcessors.addAll(currentRegistryProcessors);
            // 执行currentRegistryProcessors中存放的 BeanDefinitionRegistryPostProcessor Bean对象的 postProcessBeanDefinitonRegistry 方法
    	invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
    	currentRegistryProcessors.clear();
    }
    

    subX 还没执行过,因此得到执行。并且打印出以下输出:

    问题:为什么要自旋?
    这里之所以要“自旋”(引入while循环和reiterate变量),主要是为了解决嵌套 BeanDefinitionRegistryPostProcessor 的扫描和执行问题。BeanDefinitionRegistryPostProcessor 是一个接口,在执行它的 postProcessBeanDefinitionRegistry 方法时,可能又注册了一些新的 BeanDefinition,这些新的 BeanDefinition 又是 BeanDefinitionRegistryPostProcessor 类型的,这种类似于俄罗斯套娃一样,每一个里面都会进行一些注册,谁也不知道会进行多少层,故而需要一个死循环,只要有,就一直遍历寻找,直到执行完为止!类似与下图这样:

    问题:为什么有三段差不多的代码?
    spring 为保证不同类型,不同提供者实现的 BeanDefinitionRegistryPostProcessor 的执行顺序,而写了三段看上去差不多的代码。
    执行顺序为

    1. 首先执行 spring 内置的且实现了 PriorityOrdered 接口的后置处理器
    2. 然后执行第三方或者程序员提供的,实现了 Ordered 接口的后置处理器
    3. 最后执行第三方或者程序员提供的未处理过的后置处理器

    再接着就要执行 invokeBeanFactoryPostProcessors 方法,遍历并且执行 BeanFactoryPostProcessor.postProcessBeanFactory方法

    private static void invokeBeanFactoryPostProcessors(
    		Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    	for (BeanFactoryPostProcessor postProcessor : postProcessors) {
    		StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
    				.tag("postProcessor", postProcessor::toString);
                    // 执行 postProcessBeanFactory 方法
    		postProcessor.postProcessBeanFactory(beanFactory);
    		postProcessBeanFactory.end();
    	}
    }
    

    接着首先是遍历存放在 registryProcessors 中 BeanDefinitionRegistryPostProcessor 实现类对象,并且执行还未被执行过的父类方法 postProcessBeanFactory ,且对象顺序和刚才执行 postProcessBeanDefinitonRegistry 是一样的。

    // 按照和 postProcessBeanDefinitonRegistry 执行顺序一样的顺序执行 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory
    invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    // 执行手动添加的 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    

    至此,所有 BeanDefinitionRegistryPostProcessor 对象的 postProcessBeanDefinitonRegistry 和 postProcessBeanFactory 都按顺序执行完毕!

    -----------------------------------华丽的分割线-----------------------------------
    进入下半场 BeanFactoryPostProcessor 的执行,首先映入眼帘的是

    // 首先寻找所有 BeanFactoryPostProcesssor 类
    String[] postProcessorNames =
    		beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> 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);
    

    这段代码不难理解,先寻找所有的 BeanFactoryPostProcessor 类,初始化三个集合,分别存放实现了 PriorityOrdered, Ordered 及其他剩余的 BeanFactoryPostProcessor。
    如果是 processedBeans 中已经存在的,那么就会注解跳过,避免重复执行!
    首先被寻找出来的类,包含以下这些:

    值得注意的是

    • 如果是实现 PriorityOrdered 接口的,会直接 getBean 获取并创建实例,并将实例加入到priorityOrderedPostProcessors集合中
    • 但是实现了 Ordered 接口以及剩余的,会把 beanName 存放到 orderedPostProcessorNames 和 nonOrderedPostProcessorNames 集合中,注意此时他没有进行实例化!

    剩余的一点代码:

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    // 遍历实现了 Ordered 的 beanName集合
    for (String postProcessorName : orderedPostProcessorNames) {
            // 通过 getBean 实例化,再添加到集合中
    	orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    // Finally, invoke all other BeanFactoryPostProcessors.
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    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();
    

    总结

    总结了几条主要规律:

    • BeanDefinitionRegistryPostProcessor 早于 BeanFactoryPostProcessor 执行
    • BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry -> BeanDefinitionRegistryPostProcessor.postProcessBeanFactory -> BeanFactoryPostProcessor.postProcessBeanFactory
    • 程序员手动添加的 -> PriorityOrdered -> Ordered -> 剩余的
    • 所有的 BeanFactoryPostProcessor 及其子类 BeanDefinitionRegistryPostProcessor 不会重复执行

    手动添加 BeanFactoryPostProcessor

    首先我们要知道,给 Spring 容器提供 BeanFactoryPostProcessor 或者 BeanDefinitionRegistryPostProcessor 的 Bean 对象的方式有两种:

    • 通过加注解,让 Spring 扫描到类(把一个类交给 Spring 管理,整个类的创建过程是交给 Spring 来处理的)
    • 手动添加对象到 Spring 中(自己控制对象的实例化过程,然后再交给 Spring 管理)

    示例面试题,如何把一个对象提供给 Spring 管理?

    1. FactoryBean 是一种方式
    2. 向 BeanFactory 添加一个单例对象
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.getBeanFactory().registerSingleton("indexService", new IndexService());
    ctx.register(AppConfig.class);
    ctx.refresh();
    ctx.getBean("indexService");
    

    再回到如何手动添加 BeanFactoryPostProcessor 并提供给 Spring 管理?我们来看代码示例:

    public class ManB implements BeanFactoryPostProcessor {
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    		System.out.println("ManB ------ BeanFactoryPostProcessor, 由程序员手动添加,再交给 Spring 管理的");
    	}
    }
    
    public class ManSubY implements BeanDefinitionRegistryPostProcessor {
    	@Override
    	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    		System.out.println("ManSubY ------ BeanDefinitionRegistryPostProcessor, 由程序员手动添加,再交给 Spring 管理的");
    	}
    
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    		System.out.println("ManSubY ------ BeanFactoryPostProcessor, 由程序员手动添加,再交给 Spring 管理的");
    	}
    }
    

    这两个类都没有加上 @Component 注解,然后我们这样操作:

    public class MyApplication {
    
    	public static void main(String[] args) throws IOException {
    		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    		ctx.addBeanFactoryPostProcessor(new ManB());
    		ctx.addBeanFactoryPostProcessor(new ManSubY());
    		ctx.register(AppConfig.class);
    		ctx.refresh();
    	}
    }
    

    执行结果如图所示:

    • 程序员手动添加的 ManSubY 的父类方法率先执行
    • 程序员手动添加的 ManB 是直接实现 BeanFactoryPostProcessor 的类,在所有直接实现 BeanFactoryPostProcessor 的类中率先执行

    invokeBeanFactoryPostProcessors 完整源码

    public static void invokeBeanFactoryPostProcessors(
    		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
    	Set<String> processedBeans = new HashSet<>();
    	if (beanFactory instanceof BeanDefinitionRegistry) {
    		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    		List<BeanDefinitionRegistryPostProcessor> 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<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    		// 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, beanFactory.getApplicationStartup());
    		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, beanFactory.getApplicationStartup());
    		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, beanFactory.getApplicationStartup());
    			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<>();
    	List<String> orderedPostProcessorNames = new ArrayList<>();
    	List<String> 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<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    	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<>(nonOrderedPostProcessorNames.size());
    	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();
    }
    
  • 相关阅读:
    中国石油昆仑加油卡
    157 01 Android 零基础入门 03 Java常用工具类01 Java异常 01 异常介绍 02 异常内容简介
    156 01 Android 零基础入门 03 Java常用工具类01 Java异常 01 异常介绍 01 Java常用工具类简介
    155 01 Android 零基础入门 02 Java面向对象 07 Java多态 07 多态知识总结 01 多态总结
    154 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类 05 匿名内部类
    153 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类 04 方法内部类
    152 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类 03 静态内部类
    151 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类 02 成员内部类
    150 01 Android 零基础入门 02 Java面向对象 07 Java多态 06 内部类概述 01 内部类概述
    149 01 Android 零基础入门 02 Java面向对象 07 Java多态 05 接口(重点)07 接口的继承
  • 原文地址:https://www.cnblogs.com/kendoziyu/p/springframework-bean-factory-post-processor.html
Copyright © 2011-2022 走看看