Spring源码解析关于BeanFactoryPostProcessor

下面翻译自spring官网

使用BeanFactoryPostProcessor自定义配置元数据

我们要查看的下一个扩展点是org.springframework.beans.factory.config.BeanFactoryPostProcessor。此接口的语义与BeanPostProcessor类似,但有一个主要区别:BeanFactoryPostProcessor操作bean配置元数据。也就是说,Spring IoC容器允许BeanFactoryPostProcessor在容器实例化BeanFactoryPostProcessor实例之外的任何bean之前读取配置元数据并可能更改它。

您可以配置多个BeanFactoryPostProcessor实例,并且您可以通过设置order属性来控制这些BeanFactoryPostProcessor实例运行的顺序。但是,您只能在BeanFactoryPostProcessor实现了有序接口的情况下设置此属性。如果您编写自己的BeanFactoryPostProcessor,也应该考虑实现Ordered接口

如果希望更改实际bean实例(即从配置元数据创建的对象),则需要使用BeanPostProcessor(在前面通过使用BeanPostProcessor自定义bean中进行了描述)。虽然在BeanFactoryPostProcessor中使用bean实例在技术上是可行的(例如,通过使用BeanFactory.getBean()),但是这样做会导致过早的bean实例化,违反标准的容器生命周期。这可能会导致负面的副作用,比如绕过bean的后处理。
另外,BeanFactoryPostProcessor实例的作用域为每个容器。这只有在使用容器层次结构时才有用。如果您在一个容器中定义了BeanFactoryPostProcessor,那么它只应用于该容器中的bean定义。一个容器中的Bean定义不会被另一个容器中的BeanFactoryPostProcessor实例进行后处理,即使这两个容器属于同一层次结构。

当bean工厂后处理器在ApplicationContext中声明时,它将自动运行,以便对定义容器的配置元数据应用更改。Spring包括许多预定义的bean工厂后处理器,如PropertyOverrideConfigurer和PropertySourcesPlaceholderConfigurer。您还可以使用自定义BeanFactoryPostProcessor—例如,用于注册自定义属性编辑器。
ApplicationContext自动检测部署到其中实现BeanFactoryPostProcessor接口的任何bean。在适当的时候,它将这些bean用作bean工厂的后处理器。可以像部署任何其他bean一样部署这些后处理bean。

与BeanPostProcessors一样,您通常不希望将BeanFactoryPostProcessors配置为延迟初始化。如果没有其他bean引用bean(工厂)后处理器,则该后处理器根本不会实例化。因此,将它标记为延迟初始化将被忽略,并且即使在声明您的Bean /&gt时将default-lazy-init属性设置为true, Bean(工厂)后处理器也将被快速实例化。元素。

让我们看下BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor两个接口因为他们会贯穿invokeBeanFactoryPostProcessors方法的执行逻辑

/**
 * 允许自定义修改应用程序上下文的Bean定义,调整上下文的基础Bean工厂的Bean属性值。
 * 应用程序上下文可以在它们的bean定义中自动检测BeanFactoryPostProcessor bean,并在创建任何其他bean之前应用它们。
 * 对于针对系统管理员的自定义配置文件很有用,这些文件覆盖了在应用程序上下文中配置的Bean属性。
 * 请参阅PropertyResourceConfigurer及其具体实现,以了解解决此类配置需求的即用型解决方案。
 * BeanFactoryPostProcessor可以与bean定义进行交互并对其进行修改,但不能与bean实例进行交互。这样做可能会导致bean 实例化过早,
 * 从而违反了容器并造成了意想不到的副作用。
 */
@FunctionalInterface
public interface BeanFactoryPostProcessor {

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

}
/**
 * 对标准BeanFactoryPostProcessor SPI的扩展,允许在常规之前在之前注册更多的bean定义BeanFactoryPostProcessor检测开始。
 * 尤其是 BeanDefinitionRegistryPostProcessor可以注册更多的Bean定义反过来定义BeanFactoryPostProcessor实例。
 */
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

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

}

这里可以看出来两个方法的区别:
一个是所有常规bean定义都将被加载
一个是所有常规bean定义都将已加载。
一个是已完成一个是进行中,可以稍微理解后面两个方法的执行顺序

解析invokeBeanFactoryPostProcessors方法

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

		//首先调用BeanDefinitionRegistryPostProcessors(如果有)。
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			// 保存只实现了BeanFactoryPostProcessor接口的后处理器
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			// 保存只实现了BeanDefinitionRegistryPostProcessor接口的后处理器
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					/**
					 * 执行实现了BeanDefinitionRegistryPostProcessor接口的后处理器的
					 * postProcessBeanDefinitionRegistry方法,
					 * 注意这里执行的不是postProcessBeanFactory方法
					 */
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					/**
					 * 保存执行过了的BeanDefinitionRegistryPostProcessor,
					 * 这里执行过的BeanDefinitionRegistryPostProcessor只是代表它的特有方法:
					 * postProcessBeanDefinitionRegistry方法执行过了,
					 * 但是千万记得,它还有一个标准的postProcessBeanFactory,也就是从父接口中继承的方法还未执行
					 */
					registryProcessors.add(registryProcessor);
				}
				else {
					// 将只实现了BeanFactoryPostProcessor接口的后置处理器加入到集合中
					regularPostProcessors.add(postProcessor);
				}
			}

			/**
			 * 不要在这里初始化FactoryBeans:我们需要保留所有未初始化的常规beans
			 * 以便让bean工厂后处理器对其应用! 将实现 PriorityOrdered,Ordered和
			 * 其余的BeanDefinitionRegistryPostProcessor分开。
			 */
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			//首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessor。
			// 从容器中获取到所有实现了BeanDefinitionRegistryPostProcessor接口的Bean的名字
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				//如果当前Bean实现了 PriorityOrdered 这个接口,则当前 Bean 会被最优先调用。
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			/**
			 * 给currentRegistryProcessors排序
			 */
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 将当前将要执行的currentRegistryProcessors全部添加到registryProcessors这个集合中
			registryProcessors.addAll(currentRegistryProcessors);
			/**
			 * 循环调用 postProcessBeanDefinitionRegistry方法
			 */
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			/**
			 * 清除当前的RegistryProcessors
			 */
			currentRegistryProcessors.clear();

			// 接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessors。
			/**
			 * 如果当前 Bean 实现了 Ordered 接口,则当前 Bean 会被作为第二优先级调用:
			 */
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				/**
				 * 判断一下processedBeans是否有
				 * 当前的postProcessorName防止重复执行
				 */
				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();

			/**
			 * 最后,调用所有其他BeanDefinitionRegistryPostProcessor,直到不再出现。
			 * 所有常规bean定义都将已加载。(进行中)
			 * 所以需要循环执行
			 */
			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();
			}

			// 现在,调用到目前为止已处理的所有处理器的postProcessBeanFactory回调。
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			// 调用在上下文实例中注册的工厂处理器。
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// 不要在这里初始化FactoryBeans:我们需要保留所有常规bean
		// 未初始化,让Bean工厂后处理器对其应用!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		/**
		 * 在实现PriorityOrdered的BeanFactoryPostProcessor之间分开,
		 * Ordered 还有其余的。
		 */
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// 跳过-已在上面的第一阶段处理
			}
			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);
			}
		}

		//首先,调用实现PriorityOrdered的BeanFactoryPostProcessors。
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		//接下来,调用实现Ordered的BeanFactoryPostProcessors。
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		//最后,调用所有其他BeanFactoryPostProcessors。
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		/**
		 * 清除缓存的合并bean定义,因为后处理器可能已经修改了原始元数据,例如替换值中的占位符...
		 */
		beanFactory.clearMetadataCache();
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值