Spring源码导读之BeanFactoryPostProcessor

本文详细解析了Spring框架中BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的工作机制,包括它们的区别、优先级及调用流程,帮助读者理解如何在Bean实例化前修改Bean定义。

Spring源码导读

目录

概述

案例

源码链路跟踪

总结


 

概述

两类BeanFactoryPostProcessor:

 

public interface BeanFactoryPostProcessor {

    /**
在标准初始化后修改应用程序上下文的内部bean工厂。所有的bean定义都将被加载,但是还没有bean被实例化。这就允许重写或添加属性,甚至可以添加到渴望被初始化bean中。
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}


public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

    /**
在标准初始化后修改应用程序上下文的内部bean定义注册表。所有的常规bean定义都将被加载,但是还没有任何bean被实例化。这允许在下一个后处理阶段开始之前添加更多的bean定义。
     */
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

 

区别

BeanFactoryPostProcessor 总结来说都在Bean实例化之前可以修改Bean的定义。只是修改方式不同,BeanFactoryPostProcessor通过ConfigurableListableBeanFactory 进行修改,

BeanDefinitionRegistryPostProcessor 通过BeanDefinitionRegistry 进行修改

 

其实操作的实例都是DefaultListableBeanFactory,他是实现ConfigurableListableBeanFactory,和BeanDefinitionRegistry

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
      implements ConfigurableListableBeanFactory, BeanDefinitionRegistry

因此两种修改方式区别在于,所能获得的接口是不一样的,后面会介绍,他们的优先级也是不一样的。

 

案例

(除了BeanFactoryPostProcessor之外 在xml模式下前面提到的NameSpaceHandler也可以修改bean定义,而我们的BeanFactoryPostProcessor更加灵活,它还可以基于注解去修改bean定义)

对于基于注解的修改bean定义这里有一个案例,可以拷贝代码跑一波体会一下。

自定义BeanPostProcessor实现注册beanDefinition(模拟实现mabatis scanmapper)

 

源码链路跟踪

 

 

BeanFactoryPostProcessors第一批是在AbstractApplicationContext#invokeBeanFactoryPostProcessors创建的。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {

	// 传入beanFactory 和 List<BeanFactoryPostProcessor> beanFactoryPostProcessors 进行调用
 	// 这个方法中BeanFactoryPostProcessors将被创建和调用
	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#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List<BeanFactoryPostProcessor>) 

该方法中会有多次直接调用 BeanFactoryPostProcessor 的过程,注释中以 (第X波) 进行了标注。

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

	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
	Set<String> processedBeans = new HashSet<>();

	// 如果工厂实现了BeanDefinitionRegistry 说明是可以直接调用其注册的,那么遍历beanFactoryPostProcessors第一波
	// 并且调用里面的postProcessBeanDefinitionRegistry方法进行第一波的bean定义修改
	// 这个阶段可能会产生新的BeanFactoryPostProcessor, 就是一个BeanFactoryPostProcessor再生BeanFactoryPostProcessor的过程
	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;
						
				// (第一波)这里就直接调用了其方法进行第一波修改,可能会产生新的BeanDefinitionRegistryPostProcessor 
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				// 然后还要加入到registryProcessors中
				registryProcessors.add(registryProcessor);
			}
			else {
				// 如果不是就只是加入到 regularPostProcessors中
				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<>();

		// DefaultListableBeanFactory#getBeanNamesForType 通过类型将所有类型为BeanDefinitionRegistryPostProcessor的beanName找出来
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			// 看看这个 beanName的类型是不是还实现了PriorityOrdered(可排序)接口, 
			// 实现了PriorityOrdered的话则具有第二高优先级(仅仅次于传入的beanFactoryPostProcessors中实现了BeanDefinitionRegistryPostProcessor的),这类BeanDefinitionRegistryPostProcessor将会在这里直接被创建
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			    // 创建 BeanDefinitionRegistryPostProcessor, 并且加入到currentRegistryProcessors
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				// 加入后, 标记ppName是已经处理过的
				processedBeans.add(ppName);
			}
		}
		// 排序
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		// 排序后将currentRegistryProcessors 也加入到registryProcessors
		registryProcessors.addAll(currentRegistryProcessors);
		// (第二波) 调用 currentRegistryProcessors 中的 BeanDefinitionRegistryPostProcessor 
		// 也可能会产生新的BeanDefinitionRegistryPostProcessor 
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		// 调用完之后 将他们全部清空
		currentRegistryProcessors.clear();

		// 由于第二波可能会产生新的 BeanDefinitionRegistryPostProcessor 所以这里又进行了一次遍历,加入的过程。
		postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			// 由第一、二 波产生的新的 beanDefinitions 或者 原来就有的的beanDefinitions 中配置类型为BeanDefinitionRegistryPostProcessor 的并且实现了Ordered接口的。
			if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
				// 创建 BeanDefinitionRegistryPostProcessor, 并且加入到currentRegistryProcessors
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				// 加入后, 标记ppName是已经处理过的
				processedBeans.add(ppName);
			}
		}
		
		// 排序
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		// 排序后将这批 currentRegistryProcessors 也加入到registryProcessors
		registryProcessors.addAll(currentRegistryProcessors);
		// (第三波) 调用 currentRegistryProcessors 中的 BeanDefinitionRegistryPostProcessor 
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		// 调用完之后 将他们全部清空
		currentRegistryProcessors.clear();

		// 最后,调用所有其他BeanDefinitionRegistryPostProcessor,直到不再出现其他Processor为止。
		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);
			// (第四波) 调用 currentRegistryProcessors 中的 BeanDefinitionRegistryPostProcessor 
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// 调用完情况
			currentRegistryProcessors.clear();
		}

		// 现在,调用到目前为止处理的所有处理器的postProcessBeanFactory
		// 调用registryProcessors中的 postProcessBeanFactory 方法, 前面提到的都是调用postProcessBeanDefinitionRegistry方法
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		// 调用regularPostProcessors中的 postProcessBeanFactory
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}

	// 如果工厂没有实现BeanDefinitionRegistry 说明是不可以直接调用其注册的
	else {
		// 那么就只能调用他们的postProcessBeanFactory方法
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}
	
	// 从这里开始下面代码都是处理仅仅实现了BeanFactoryPostProcessor而没有实现BeanDefinitionRegistryPostProcessor的processor

	// Do not initialize FactoryBeans here: We need to leave all regular beans
	// uninitialized to let the bean factory post-processors apply to them!
	
	// 查找BeanFactoryPostProcessor的bean定义
	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
		}
		// 如果实现了 PriorityOrdered 优先级最高 加入priorityOrderedPostProcessors
		else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			// 如果实现了 Ordered 优先级次之 加入priorityOrderedPostProcessors
			orderedPostProcessorNames.add(ppName);
		}
		else {
			// 优先级最低
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// priorityOrderedPostProcessors的排序和调用
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    

	// orderedPostProcessors 的排序、创建和调用
	// 为什么orderedPostProcessors 和 nonOrderedPostProcessor 在前面只是记录名称,在后面才修改?
	// 因为 priorityOrderedPostProcessors 中的调用可能会修改他们的bean定义
	List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
	for (String postProcessorName : orderedPostProcessorNames) {
		orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

	// nonOrderedPostProcessor 的创建和调用
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
	for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

	// 我们看见 仅仅实现BeanFactoryPostProcessor的processor在这里并没有循环调用。
	// 说明Spring并不支持我们在BeanFactoryPostProcessor中产生新的BeanFactoryPostProcessor, 他们将不会被调用
	
	// Clear cached merged bean definitions since the post-processors might have
	// modified the original metadata, e.g. replacing placeholders in values...
	beanFactory.clearMetadataCache();
}

优先级:

第一优先级: invokeBeanFactoryPostProcessors方法传入的BeanFactoryPostProcessor并且实现了BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法调用。

第二优先级: 由第一 波产生的新的 beanDefinitions 或者 原来就有的的beanDefinitions 中配置类型为BeanDefinitionRegistryPostProcessor的并且实现了PriorityOrdered接口的postProcessBeanDefinitionRegistry方法调用

第三优先级: 由第一、二 波产生的新的 beanDefinitions 或者 原来就有的的beanDefinitions 中配置类型为BeanDefinitionRegistryPostProcessor的并且实现了Ordered接口的 postProcessBeanDefinitionRegistry方法调用。

第四优先级: 由第一、二 、三 波产生的新的 beanDefinitions 或者 原来就有的的beanDefinitions 中配置类型为BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry方法调用。这里是循环直到找不到,新的beanFactoryPostProcessors为止。

第五优先级:所有的实现了BeanDefinitionRegistryPostProcessor的 postProcessBeanFactory方法调用

第六优先级:invokeBeanFactoryPostProcessors方法传入的BeanFactoryPostProcessor 的实现了BeanFactoryPostProcessor但没有实现BeanDefinitionRegistryPostProcessor 的  postProcessBeanFactory方法调用.

第七优先级:所有 beanDefinitions 中配置类型为BeanFactoryPostProcessor 并且实现了PriorityOrdered的 postProcessBeanFactory的方法调用。

第八优先级:所有 beanDefinitions 中配置类型为BeanFactoryPostProcessor 并且实现了Ordered的 postProcessBeanFactory的方法调用。

第九优先级:所有 beanDefinitions 中配置类型为BeanFactoryPostProcessor 的 postProcessBeanFactory的方法调用。

 

一、二、三、四 都是 调用 postProcessBeanDefinitionRegistry方法

五、六、七、八、九 都是 调用 postProcessBeanFactory方法

 

总结

1、优先级:

postProcessBeanDefinitionRegistry >  postProcessBeanFactory方法

方法传入的 > PriorityOrdered > Ordered > 没有实现排序的

2、Spring不鼓励我们在postProcessBeanFactory方法中定义新的BeanFactoryPostProcessor

从标红的这个注释我们看到Spring让我们不要再postProcessBeanFactory方法中定义新的BeanFactoryPostProcessor,这里产生新的BeanFactoryPostProcessor将不会被调用。(但是除了是方法传进来的那些BeanFactoryPostProcessor 中产生的BeanFactoryPostProcessor)

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值