spring BeanFactory扩展点:BeanFactoryPostProcessor 后置处理接口

本文详细介绍了Spring中BeanFactoryPostProcessor扩展点的作用和使用,包括其在容器初始化时对BeanDefinition的修改,以及与BeanDefinitionRegistryPostProcessor的区别。文章通过代码示例和分析解释了BeanFactoryPostProcessor的执行时机、注入方式和执行顺序,帮助读者深入理解Spring的容器扩展机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

通过上一篇spring bean扩展点:后处理器 BeanPostProcessor,我们知道 BeanPostProcessor是用来改变bean实例的。同样在 Spring 容器启动阶段,Spring 也提供了一种容器扩展机制:BeanFactoryPostProcessor,该机制作用于容器启动阶段,允许我们在容器实例化 Bean 之前对注册到该容器的 BeanDefinition 做出修改。

BeanFactoryPostProcessor 为spring在容器初始化时对外对外暴露的扩展点,Spring IoC容器允许BeanFactoryPostProcessor在容器加载注册BeanDefinition完成之后读取BeanDefinition(配置元数据),并可以修改它。如果业务需要,可以配置多个BeanFactoryPostProcessor的实现类,通过”order”控制执行次序(要实现Ordered接口)

PS : 个人感觉,实现IOC的两个核心后处理器 :

  • ConfigurationClassPostProcessor 解析配置类(这里的配置类不仅仅局限于@Configuration 注解,还包括 @Import、 @ImportResource 等注解),将解析到的需要注入到Spring容器中的bean的BeanDefinition保存起来
  • AutowiredAnnotationBeanPostProcessor 解析bean中的 需要自动注入的bean @Autowired 和 @Inject @Value注解。

其中 ConfigurationClassPostProcessor 就是BeanFactory 后置处理器实现类

1.1、三重要的 BeanFactory扩展点

  • 1、ImportBeanDefinitionRegistrarregisterBeanDefinitions() 方法
  • 2、BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry方法
  • 3、BeanFactoryPostProcessor postProcessBeanFactory方法

由于AnnotationConfigApplicationContext#refresh()容器生命周期中invokeBeanFactoryPostProcessors 方法中主要就是对BeanFactoryPostProcessor 的处理,所以这里简单的介绍一下 BeanFactoryPostProcessor 及其子接口 BeanDefinitionRegistryPostProcessor。其结构如下图:

BeanFactoryPostProcessor 相比较于 BeanPostProcessor 方法是很简单的,只有一个方法,其子接口也就一个方法。但是他们俩的功能又是类似的,区别就是作用域并不相同BeanFactoryPostProcessor的作用域范围是容器级别的。它只和你使用的容器有关。如果你在容器中定义一个BeanFactoryPostProcessor ,它仅仅对此容器中的bean进行后置处理。BeanFactoryPostProcessor 不会对定义在另一个容器中的bean进行后置处理,即使这两个容器都在同一容器中。
BeanFactoryPostProcessor 可以对 bean的定义(配置元数据)进行处理。Spring IOC 容器允许 BeanFactoryPostProcessor 在容器实际实例化任何其他bean之前读取配置元数据,并有可能修改它,也即是说 BeanFactoryPostProcessor 是直接修改了bean的定义,BeanPostProcessor 则是对bean创建过程中进行干涉。

BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 的区别在于:

  • BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法针对是BeanDefinitionRegistry类型的ConfigurableListableBeanFactory,可以实现对BeanDefinition的增删改查等操作,但是对于非 ConfigurableListableBeanFactory 类型的BeanFactory,并不起作用。

  • BeanFactoryPostProcessor#postProcessBeanFactory 针对的是所有的BeanFactory

  • postProcessBeanDefinitionRegistry 的调用时机在postProcessBeanFactory 之前

1.2 、代码示例:

/**
 * 和BeanPostProcessor原理一致,Spring提供了对BeanFactory进行操作的处理器BeanFactoryProcessor,简单来说就是获取容器BeanFactory,这样就可以在真正初始化bean之前对bean做一些处理操作。
 * 允许我们在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行修改也可以add属性值。
 * **/
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor{

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessBeanFactory");
        //获取BeanDefinition   
       

        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myTestBean");
        System.out.println("修改属性name值");
        beanDefinition.getPropertyValues().add("name", "liSi");


    }

}

二、代码分析

接口代码:

为了更好的了解下面的代码,我们先了解几个代码中的规则:

BeanFactoryPostProcessor的接口:

BeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor 在本次分析中分为两种类型: BeanFactoryPostProcessor 和其子接口 BeanDefinitionRegistryPostProcessor 。BeanDefinitionRegistryPostProcessor 相较于 BeanFactoryPostProcessor ,增加了一个方法如下。

需要注意的是,BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 这个方法仅仅针对于 BeanDefinitionRegistry 类型的 BeanFactory 生效,这一点根据其入参就可以看到。
总结一下即 : BeanFactoryPostProcessor 针对所有的 BeanFactory ,即对于所有类型的BeanFactory 都会调用其方法;BeanDefinitionRegistryPostProcessor 仅对 BeanDefinitionRegistry 子类的BeanFactory 起作用,非BeanDefinitionRegistry类型则直接处理即可。

BeanFactoryPostProcessor 的注入分为两种方式:

       配置注入方式:即通过注解或者xml的方式动态的注入到容器中的BeanFactoryPostProcessor

       硬编码注入方式: 这种方式是直接调用 void addBeanPostProcessor(BeanPostProcessor beanPostProcessor); 方法将 BeanFactoryPostProcessor 添加到 BeanFactory.beanPostProcessors 属性中。其中


硬编码注入的BeanFactoryPostProcessor 并不需要也不支持接口排序,而配置注入的方式因为Spring无法保证加载的顺序,所以通过支持PriorityOrdered、Ordered排序接口的排序。


在下面代码分析中会由四个集合

  • regularPostProcessors : 记录通过硬编码方式注册的BeanFactoryPostProcessor 类型的处理器
  • registryProcessors:记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessor 类型的处理器
  • currentRegistryProcessors : 记录通过配置方式注册的 BeanDefinitionRegistryPostProcessor 类型的处理器
  • processedBeans : 记录当前已经处理过的BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor

执行时机:

在上面标红的:在refresh方法中有如下一行:

//执行容器工厂的后置处理器,
invokeBeanFactoryPostProcessors(beanFactory);

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		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()));
		}
	}

invokeBeanFactoryPostProcessors 方法很简单,通过PostProcessorRegistrationDelegate类的静态方法invokeBeanFactoryPostProcessors执行后置处理器。此方法完成两件事:

  1. 调用getBeanFactoryPostProcessors()方法获取手工注册到ApplicationContext的容器后置处理器集合
  2. 调用静态方法invokeBeanFactoryPostProcessors并传入后置处理器集合批量执行后置处理器

可以看到主要功能还是在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); 这一句上。我们先来看看 getBeanFactoryPostProcessors() 得到的是什么

getBeanFactoryPostProcessors()

	private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
		
	@Override
	public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
		Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
		this.beanFactoryPostProcessors.add(postProcessor);
	}

	/**
	 * Return the list of BeanFactoryPostProcessors that will get applied
	 * to the internal BeanFactory.
	 */
	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
		return this.beanFactoryPostProcessors;
	}

可以看到 getBeanFactoryPostProcessors() 方法仅仅是将 beanFactoryPostProcessors 集合返回了出去而已。那么 beanFactoryPostProcessors 集合是通过 set方法添加的。这就是我们上面提到过的,beanFactoryPostProcessors 实际上是 硬编码形式注册的BeanDefinitionRegistryPostProcessor 类型的处理器集合。

invokeBeanFactoryPostProcessors

通过上一步,我们可以知道 入参中的 beanFactoryPostProcessors 集合是硬编码注册的 集合。对于下面的分析我们就好理解了。

下面代码主要是对于 BeanDefinitionRegistry 类型 BeanFactory的处理以及 BeanFactoryPostProcessor 调用顺序问题的处理。实际上并不复杂。其主要逻辑如下

主要是在 PostProcessorRegistrationDelegate  中多次循环处理先处理 BeanDefinitionRegistryPostProcessor 的接口的实现类中的 postProcessBeanDefinitionRegistry() 方法。

     然后在处理BeanFactoryPostProcessor 实现类中的postProcessBeanFactory() 方法

1、处理BeanDefinitionRegistryPostProcessor 接口的所有子类

  • 首先执行程序员通过 api的addBeanFactoryPostProcessor();
  • 然后执行spring内置的 ----ConfigurationClassPostProcessor 和程序员提供的 而且实现 PriorityOrdered 接口的
  • 在执行实现 Ordered 接口的 后置处理器 。
  • 程序员 提供的 没有任何特点的 BeanDefinitionRegistryPostProcessor 的接口的实现类中的 postProcessBeanDefinitionRegistry() 方法。

2、处理 BeanFactoryPostProcessor 实现类中的postProcessBeanFactory() 方法

  • 首先执行的是 实现了 BeanDefinitionRegistryPostProcessor 而且实现了 其父类 BeanFactoryPostProcessor的postProcessBeanFactory() 方法
  • 执行 BeanFactoryPostProcessor 直接子类 ----postProcessBeanFactory的方法

 

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

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();
        //90% 会进来
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			//里面存放的是 常规的 BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
			//里面存放的是 BeanDefinitionRegistryPostProcessor
			//存放所有的 BeanDefinitionRegistryPostProcessor
			//存放所有的内置的 BeanDefinitionPostProcessor
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();

			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.
			//TODO 策略模式 表示当前的
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
            //TODO  根据类型从 BeanDefinition map当中找到名字
			//这里 只能找到一个
			// 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)) {
					//当前当前执行的类
					//TODO 这个类是 ConfigurationClassPostProcessor 很重要的 实现了PriorityOrdered 所以成立
					//而且是bean 工厂的后置处理器
					//TODO ****很重要的**** 这里其实就实例化bean 了  beanFactory.getBean()
					// 1、直接从容器中获取bean对象 2、如果没有 这实例化这个bean
					// 为什么要实例化 为了后继调用方法
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);//这个存的是名字,会存放所有的
				}
			}
			//进行排序 仅对当前的
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//
			registryProcessors.addAll(currentRegistryProcessors);
			//TODO ConfigurationClassPostProcessor 接口中的  postProcessBeanDefinitionRegistry
			//完成扫描
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			//清空当前需求执行的 类
			currentRegistryProcessors.clear();
            //TODO 下面是继续中 实现 执行的是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);
			//执行的是BeanDefinitionRegistryPostProcessor 接口中的  postProcessBeanDefinitionRegistry
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			//
			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);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			//执行所有的 BeanDefinitionRegistryPostProcessor 接口的
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			//执行 程序猿提供的BeanFactoryPostProcessors的直接实现方法
			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!
		// 继续实现BeanFactoryPostProcessor 接口的实现类
		//TODO 首先执行的是 实现了 BeanDefinitionRegistryPostProcessor
		// 而且实现了 其父类 BeanFactoryPostProcessor的postProcessBeanFactory() 方法
		// 具体执行的是 ConfigurationClassPostProcessor 中的实现了 BeanFactoryPostProcessor的postProcessBeanFactory
		// 找出程序员提供的 通过主键提供的
		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<>();
		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<>();
		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类型

在上面看到spring主要将BeanFactoryPostProcessor划分了两类:

  • 正常的BeanFactoryPostProcessor
  • BeanDefinitionRegistry类型的BeanDefinitionRegistryPostProcessor

在执行流程中可以看到spring先执行了BeanDefinitionRegistryPostProcessor类型的postProcessBeanDefinitionRegistry方法,再执行BeanDefinitionRegistryPostProcessor和正常BeanFactoryPostProcessor的postProcessBeanFactory方法。

spring对BeanDefinitionRegistryPostProcessor的解释是:允许在正常的BeanFactoryPostProcessor执行检测开始之前注册更多的自定义bean。也就是说BeanDefinitionRegistryPostProcessor的方法postProcessBeanDefinitionRegistry可以在后置处理器执行前自定义注册更多的BeanDefinition。

例如:spring实现的ConfigurationClassPostProcessor用于注册注解@Configuration标识的类里面定义的BeanDefinition

BeanFactoryPostProcessor执行的优先级:

  1. 首先是实现了PriorityOrdered接口的,排序执行
  2. 下来是实现了Ordered接口的,排序执行
  3. 最后是其它(未实现排序接口),顺序执行

BeanFactoryPostProcessor获取机制:

  1. 首先获取手动注册ApplicationContext的集合
  2. 再次是通过beanFactory.getBeanNamesForType查找所有已注册的BeanFactoryPostProcessor的bean定义并实例化。

下面有一个简单的流程图:

在这里插入图片描述

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值