springBean注册之后置处理器BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor

前言

本文重点研究BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的区别和执行时机

一、方法说明

1、BeanFactoryPostProcessor

BeanFactoryPostProcessor允许使用者修改容器中的Beandefinitions

BeanFactoryPostProcessor可以与Beandefinitions打交道,但是千万不要进行bean实例化(感觉这里应该说的是不要在BeanFactoryPostProcessor进行可能触发bean实例化的操作)。这么做可能会导致bean被提前实例化,会破坏容器造成预估不到的副作用。如果你需要控制bean实例化过程,请考虑使用BeanPostProcessor

public interface BeanFactoryPostProcessor {

	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

利用他,我们可以获取Beandefinition(未实例化)数据,可以随心所欲的修改属性

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

		System.out.println("调用了自定义的BeanFactoryPostProcessor " + beanFactory);
		Iterator it = beanFactory.getBeanNamesIterator();

		String[] names = beanFactory.getBeanDefinitionNames();
		// 获取了所有的bean名称列表
		for(int i=0; i<names.length; i++){
			String name = names[i];
			BeanDefinition bd = beanFactory.getBeanDefinition(name);
			//利用BeanDefinition方法改变当前BeanDefinition
		
	    }
	}
}

2、BeanDefinitionRegistryPostProcessor

BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口

他和BeanFactoryPostProcessor的区别是什么?

BeanDefinitionRegistryPostProcessors表示BeanDefinitionRegistry后置处理器,可以通过实现BeanDefinitionRegistryPostProcessors接口,来向BeanDefinitionRegistry中添加BeanDefinition,并且BeanDefinitionRegistryPostProcessors本身也是一个beanFactory后置处理器。BeanDefinitionRegistryPostProcessors既可以添加BeanDefinition,也可以修改BeanDefinition。

通俗的说我们可以利用BeanDefinitionRegistryPostProcessors手动注入BeanDefinition,而BeanFactoryPostProcessor只能修改现有BeanDefinition的属性

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

@Configuration注解处理器ConfigurationClassPostProcessor就是一个BeanDefinitionRegistryPostProcessor

二、实例化并调用BeanFactoryPostProcessor

代码发生在refresh方法的invokeBeanFactoryPostProcessors(beanFactory)模块中

final class PostProcessorRegistrationDelegate {
         public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
		//储存执行过的BeanFactoryPostProcessor
		Set<String> processedBeans = new HashSet<>();

		//只有此beanFactory 是BeanDefinitionRegistry  才能执行BeanDefinitionRegistryPostProcessor,才能修改Bean的定义嘛~
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

			//装载普通的BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			//装载和Bean定义有关的 BeanDefinitionRegistryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 这里是我们自己的set进去的,若没set,这里就是空(若是Sprng容器里的,下面会处理,见下面)
			// 从此处可以看出,我们手动set进去的,最最最最有限执行的
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					// 这里执行post方法,然后然后吧它缓冲起来了,放在了registryProcessors里
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					// 缓冲起来常规的处理器
					regularPostProcessors.add(postProcessor);
				}
			}


			// 接下来,就是去执行Spring容器里面的一些PostProcessor了。他们顺序doc里也写得很清楚:
			// 先执行实现了PriorityOrdered接口的,然后是Ordered接口的,最后执行剩下的
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();


			//获取所有的BeanDefinitionRegistryPostProcessor类型BeanDefinition的名字
			//如ConfigurationClassPostProcessor(@Configuration注解处理器)的名字
			String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

			//TODO 实例化和执行PriorityOrdered类型的BeanDefinitionRegistryPostProcessor
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// processedBeans也顺带保存了一份,保存的是bean的Name哦~
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			// 排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 此处缓冲起来(需要注意的是,是排序后,再放进去的 这样是最好的)
			registryProcessors.addAll(currentRegistryProcessors);
			// 这个方法很简单,就是吧currentRegistryProcessors里面所有的处理器for循环一个个的执行掉
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// 此处把当前持有的执行对象给清空了,需要注意。以方便装载后续执行的处理器们
			currentRegistryProcessors.clear();



			//TODO 此处逻辑完全同上,实例化和执行Ordered类型的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));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

             //TODO 最后执行,实例化和执行两个排序接口都没有实现的BeanDefinitionRegistryPostProcessor们
			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();
			}

			//执行上面实例化过所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {

			// 若是普通的Bean工厂,就直接执行set进来的后置处理器即可(因为容器里就没有其它Bean定义了)
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		//获取所有的BeanFactoryPostProcessor类型BeanDefinition的名字
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		//存放实现PriorityOrdered接口的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		//存放实现Ordered接口的BeanFactoryPostProcessor
		List<String> orderedPostProcessorNames = new ArrayList<>();
		//存放上面2个接口都没有实现的BeanFactoryPostProcessor
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {

			if (processedBeans.contains(ppName)) {
				//如果当前BeanFactoryPostProcessor已经执行过了,忽略
			}
			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);
			}
		}

		// TODO 执行实现PriorityOrdered接口的BeanFactoryPostProcessor
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);


		// TODO Next 执行实现Ordered接口的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// TODO Finally 执行实现剩下的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		//清除缓存的合并bean定义,因为后处理器可能有
        //修改了原始元数据,例如替换值中的占位符。。。
		beanFactory.clearMetadataCache();
	}

1、获取容器中所有的BeanDefinitionRegistryPostProcessor类型BeanDefinition的名字

2、实例化并执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor

3、实例化并执行实现Ordered接口的BeanDefinitionRegistryPostProcessor

4、实例化并执行上面两个排序接口都没有实现的BeanDefinitionRegistryPostProcessor

5、调用上述所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法

6、获取容器中所有的BeanFactoryPostProcessor类型BeanDefinition的名字

7、实例化并执行实现PriorityOrdered接口的BeanFactoryPostProcessor

8、实例化并执行实现Ordered接口的BeanFactoryPostProcessor

9、实例化并执行上面两个排序接口都没有实现的BeanFactoryPostProcessor

发布了34 篇原创文章 · 获赞 0 · 访问量 1352

猜你喜欢

转载自blog.csdn.net/qq_41071876/article/details/105388829
今日推荐