Spring源码 - 容器刷新#invokeBeanFactoryPostProcessors()

2022/1/9 14:34:04

本文主要是介绍Spring源码 - 容器刷新#invokeBeanFactoryPostProcessors(),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

# Spring源码 - 容器刷新#invokeBeanFactoryPostProcessors()

Spring版本:Spring 5.3.13-release


# 1、invokeBeanFactoryPostProcessors()将工厂的处理器作为Bean激活到IOC容器中

这一步的作用是调用各种BeanFactory的增强处理器。其中最为关键的就是ConfigurationClassPostProcessor,这个增强处理器完成了对配置类的解析,将解析得到将要注册的BeanBeanDefinition

AbstractApplicationContext#invokeBeanFactoryPostProcessors()代码:

	/**
	 * 根据顺序, 实例化并注册所有的 BeanFactoryPostProcessor Bean 实例
	 * 
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// getBeanFactoryPostProcessors() 直接返回通过硬编码形式注册的 BeanFactoryPostProcessor 类型的处理器集合
		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)
		// 通过类加载器织入, loadTimeWeaver (LOAD_TIME_WEAVER_BEAN_NAME)
		if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

主要注册BeanFactoryPostProcessor的代码就是:

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

先看看getBeanFactoryPostProcessors()得到的是什么,AbstractAplicationContext#getBeanFactoryPostProcessors()代码:

	@Override
	public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
		Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
		this.beanFactoryPostProcessors.add(postProcessor);
	}

	/**
	 * 返回通过 addBeanFactoryPostProcessor() 方法添加的用于内部 BeanFactory 的 BeanFactoryPostProcessor 集合
	 * @see AbstractApplicationContext#addBeanFactoryPostProcessor(BeanFactoryPostProcessor)
	 *
	 * Return the list of BeanFactoryPostProcessors that will get applied
	 * to the internal BeanFactory.
	 */
	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
		// 直接返回 BeanFactoryPostProcessor
		return this.beanFactoryPostProcessors;
	}

可以看到getBeanFactoryPostProcessors()就是直接返回用于内部BeanFactoryBeanFactoryPostProcessor集合。

那么这一句就很简单了,此处传递的参数就是内部BeanFactory和所有作用于内部BeanFactoryBeanFactoryPostProcessor

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

# 2、BeanFactory的增强处理器

在看invokeBeanFactoryPostProcessors()具体实现的代码之前,先说一下BeanFactory的增强处理器:

# 1、BeanFactoryPostProcessor接口

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;

}
     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. 

从官方给出的接口注释中可以看出:

  • 可以在容器中的内部BeanFactory在进行标准初始化之后对其进行修改。此时所有的BeanDefintion已经全部加载完毕,但是Bean还没开始实例化。

所以Spring官方在注释文档中已经非常明确的说明了这个接口的用处:

  • 在所有的BeanDefintion加载完成之后,Bean进行实例化之前,对BeanDefintion做一些定制化操作,比如说修改某个BeanBeanDefinition

# 2、BeanDefintionRegistryPostProcessor接口:

BeanDefinitionRegistryPostProcessor代码:

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;

}

可以看到BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor子接口,所以看看类图先:

在这里插入图片描述

	 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.

从官方给出的接口注释中可以看出:

  • 可以在容器中的内部BeanFactory在进行标准初始化之后对其进行修改。此时所有常规的BeanDefinition已经全部加载完毕,但是Bean还没开始实例化。这允许在下一个Psot Processing阶段之前继续添加BeanBeanDefintion

所以Spring官方在注释文档中已经非常明确的说明了这个接口的用处:

  • 在所有的常规BeanDefintion加载完成之后,Bean进行实例化之前,下一个Post Processing阶段之前继续添加BeanBeanDefintion

# 3、BeanDefinitionRegistryPostProcessor & BeanFactoryPostProcessor 接口执行顺序

由此也可以推断出BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的执行顺序,BeanDefinitionRegistryPostProcessor必然是优先于BeanFactoryPostProcessor执行的。官方注释文档已经说的非常清楚了,BeanFactoryPostProcessor是所有BeanDefintion加载完毕Bean实例化之前。

# 4、BeanFactoryPostProcessor注入方式

BeanFactoryPostProcessor接口的注入方式有两种:

  • 配置注入:通过XML配置文件或者配置类的方式动态注入到容器中。
  • 硬编码注入:直接调用AbstractApplicationContext#addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)方法将需要注入的BeanFactoryPostProcessor添加到AbstractApplicationContext#beanFactoryPostProcessors集合中。

通过硬编码注入的BeanFactoryPostPrcoessor并不需要同时也不支持接口排序,因为在添加时就是有先后顺序的。而通过上述配置注入的,因为Spring无法保证加载的先后顺序,所以通过配置注入的BeanFactoryPostProcessor支持PriorityOrderedOrdered排序接口的排序。


3、invokeBeanFactoryPostProcessors()的具体实现

通过上面的描述,已经知道了:

  • BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor子接口。BeanDefinitionRegistryPostProcessor子接口中需要BeanDefinitionRegistry类型的BeanFactory,非BeanDefinitionRegistry类型的BeanFactory交由BeanFactoryPostProcessor父接口进行激活。

  • BeanFactoryPostProcessor的注入方式分为配置与硬编码两种。同时配置注入支持接口排序,而硬编码注入是不需要接口排序的。

接下来的源码,Spring就是围绕上面的两点进行BeanFactoryPostProcessor的具体激活代码实现。

invokeBeanFactoryPostProcessors()的具体实现是PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()方法。

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

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

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

		// 对于 BeanDefinitionRegistry 类型的处理, 这里是交由 BeanDefinitionRegistryPostProcessor 来处理
		// 判断 BeanFactory 的类型, 如果是 BeanDefinitionRegistry 的子类,
		// 则交由 BeanDefinitionRegistryPostProcessor 处理, 否则直接按照 BeanFactoryPostProcessor 进行处理
		// 由于 BeanDefinitionRegistryPostProcessor 只能处理 BeanDefinitionRegistry 的子类, 所以这里必须先进行 beanFactory 的区分
		if (beanFactory instanceof BeanDefinitionRegistry) {
			// 以下逻辑看似复杂其实大体就是两步
			// 1.获取所有硬编码的 BeanDefinitionRegistryPostProcessor 类型, 激活 postProcessBeanDefinitionRegistry 方法
			// 2.获取所有配置的 BeanDefinitionRegistryPostProcessor 类型, 激活 postProcessBeanDefinitionRegistry 方法

			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

			// 记录通过硬编码方式注册的 BeanFactoryPostProcessor 类型处理器
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			// 记录通过硬编码方式注册的 BeanDefinitionRegistryPostProcessor 类型处理器
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
			// 遍历所有硬编码注册的 BeanFactoryPostProcessor 处理器
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				// 如果是 BeanDefinitionRegistryPostProcessor 类型的处理器
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					// 将 BeanFactoryPostProcessor 强制类型转换为 BeanDefinitionRegistryPostProcessor
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					// 激活(调用) BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					// 将其保存到 registryProcessors 中
					registryProcessors.add(registryProcessor);
				}
				else {
					// 将非 BeanDefinitionRegistryPostProcessor 类型的硬编码处理器注入对象直接保存到 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.
			// 用于记录通过配置方式注册的 BeanDefinitionRegistryPostProcessor 类型的处理器
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 获取所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName
			String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			// 遍历所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName
			for (String ppName : postProcessorNames) {
				// 筛选出 PriorityOrdered 接口的实现类, 用于优先执行
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 从容器中获取 BeanName 对应的 BeanDefinitionRegistryPostProcessor 类型的 Bean 实例, 并将其添加到 currentRegistryProcessors 中
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					// 记录 BeanName 对应的 BeanDefinitionRegistryPostProcessor 已经处理
					processedBeans.add(ppName);
				}
			}
			// 对实现 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor 类型的 Bean 进行排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 将其添加到 registryProcessors 中
			registryProcessors.addAll(currentRegistryProcessors);
			// 激活 postProcessBeanDefinitionRegistry 方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			// 执行完后将集合清空
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// 获取所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			// 遍历所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName
			for (String ppName : postProcessorNames) {
				// 筛选出未经过处理的 && 实现 Ordered 接口的实现类, 用于第二执行
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					// 从容器中获取 BeanName 对应的 BeanDefinitionRegistryPostProcessor 类型的 Bean 实例, 并将其添加到 currentRegistryProcessors 中
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					// 记录 BeanName 对应的 BeanDefinitionRegistryPostProcessor 已经处理
					processedBeans.add(ppName);
				}
			}

			// 对实现 Ordered 接口的 BeanDefinitionRegistryPostProcessor 类型的 Bean 进行排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 将其添加到 registryProcessors 中
			registryProcessors.addAll(currentRegistryProcessors);
			// 激活 postProcessBeanDefinitionRegistry 方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			// 执行完后将集合清空
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			// 最后获取没有实现排序接口的 BeanDefinitionRegistryPostProcessor 类型的 Bean 进行激活,
			// 直到所有的 BeanDefinitionRegistryPostProcessors 类型注册的子类全部处理完毕才会退出 while 循环
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				// 获取所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				// 遍历所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName
				for (String ppName : postProcessorNames) {
					// 将剩余(未实现 PriorityOrdered 和 Ordered 排序接口的子类)未处理过的 BeanName
					if (!processedBeans.contains(ppName)) {
						// 从容器中获取 BeanName 对应的 BeanDefinitionRegistryPostProcessor 类型的 Bean 实例, 并将其添加到 currentRegistryProcessors 中
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						// 记录 BeanName 对应的 BeanDefinitionRegistryPostProcessor 已经处理
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				// 排序
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				// 将其添加到 registryProcessors 中
				registryProcessors.addAll(currentRegistryProcessors);
				// 激活 postProcessBeanDefinitionRegistry 方法
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
				// 执行完后将集合清空
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			// 至此, 所有的 BeanDefinitionRegistryPostProcessor 类型对象的 postProcessBeanDefinitionRegistry 方法已经全部激活完毕,
			// 开始激活其 postProcessBeanFactory 方法。
			// registryProcessors 记录的是所有通过硬编码注册的 BeanDefinitionRegistryPostProcess
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			// regularPostProcessors 记录的是所有通过硬编码注册的 BeanFactoryPostProcessor
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		// 如果 beanFactory instanceOf BeanDefinitionRegistry 为 false
		// 则直接执行 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法即可。
		// 因为 BeanDefinitionRegistryPostProcessor 接口中定义的 postProcessBeanDefinitionRegistry 方法需要的参数类型为 BeanDefinitionRegistry 类型的 BeanFactory
		else {
			// Invoke factory processors registered with the context instance.
			// 直接激活使用硬编码注册的 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}
		// 至此, 所有通过硬编码注册的 BeanFactoryPostProcessor 已全部处理完成, 下面开始处理通过配置注册的后置处理器

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		// 获取所有的 BeanFactoryPostProcessor 类型的后置处理器的 BeanName, 用于后续处理
		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<>();
		// 遍历获取的所有 BeanFactoryPostProcessor 类型的后置处理器的 BeanName
		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.
		// 激活实现了 Ordered 排序接口的 BeanFactoryPostProcessor
		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.
		// 激活没有实现任何排序接口的 BeanFactoryPostProcessor
		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();
	}

源码具体实现很长,但是总结出来就我上面说的两点的具体实现。

至此,所有的BeanFactoryPostProcessor已全部注册到容器中并且激活。

GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13

备注:此文为笔者学习Spring源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。



这篇关于Spring源码 - 容器刷新#invokeBeanFactoryPostProcessors()的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程