spring 源码执行BFPP invokeBeanFactoryPostProcessors (1)

上篇传送门

上篇咱们了解了工厂创建,bean定义信息的加载,这篇咱们来探索下BFPP

BFPP大体了解

BFPP作用

  1. 处理对Bean工厂扩展(继承)
  2. 对注解支持解析
  3. 对Bean定义信息扩展(BDRPP)
  4. 对BFPP实现类处理并进行扩展
  5. 对属性进行替换(配置文件,占位符)

源码之前先了解两个接口的作用

  1. BeanFactoryPostProcessor 对工厂进行增强(bean定义信息解析之后,bean实例化前)
  2. BeanPostProcessor 对bean的初始化前后进行增强

上面两个接口作用后咱们再看下两个接口的关系

  1. BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
  2. BeanDefinitionRegistryPostProcessor BDRPP实现了BFPP
  3. BeanDefinitionRegistryPostProcessor 是Bean定义信息的注册器,对Bean定义信息增删改操作

执行流程
在这里插入图片描述
咱们在这个方法中学到了什么

  1. 对bean增强咱们可以使用BDRPP或BFPP
  2. 获取缓存中对象getBeanNamesForType,还有另外类似的方法供咱们平常开发中使用(getBeansForType)
  3. 责任链模式

AbstractApplicationContext.invokeBeanFactoryPostProcessors 执行BFPP

源码

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	//执行BFPP
	//getBeanFactoryPostProcessors() 外部的BFPP
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
	// 动态代理支持及织入支持
	// 处理 -javaagent:\path\xxx.jar  处理成BPP
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors 执行BFPP
public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

	// 记录已经处理过的BFPP
	Set<String> processedBeans = new HashSet<>();

	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		//存放BFPP
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		//存放执行过的BDRPP
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
		
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			//把传过来的BFPP进行区分,先执行BDRPP
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			}
			else {
				regularPostProcessors.add(postProcessor);
			}
		}
		// 保存当前需要执行的BDRPP
		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
		// 在bean定义信息中获取所有BDRPP ,这里先执行实现了PriorityOrdered接口的对象
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 获取Bean实例,这里实例化后,方便下面进行调用
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				// 将要执行的BFPP添加到processedBeans,避免后续重复执行
				processedBeans.add(ppName);
			}
		}
		// 排序
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		// 添加到已执行过的集合中
		registryProcessors.addAll(currentRegistryProcessors);
		//执行
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		// 清空 方便后面继续使用
		currentRegistryProcessors.clear();

		// 这里再次获取,执行实现Ordered的借口的BDRPP(这里逻辑和前面非常相似)
		//这里为什么要重复获取呢?因为当咱们执行invoke的时候有可能会添加新的BDRPP(就是添加新的BeanDefiniton)
		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();

		// 处理普通的BDRPP
		boolean reiterate = true;
		while (reiterate) {
			reiterate = false;
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			//过滤掉已经执行的BDRPP
			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();
		}

		// 上面已经执行过BDRPP,接下来执行所有的BFPP(registryProcessors优先级在上面已经定义好了,接下来就是按照上面执行的顺序依次调用)
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}else {
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}

	// 获取BFPP,为什么需要重新获取呢?上面不是已经获取过了BDRPP了?
	//因为存在一个类实现了BDRPP而未实现BFPP的可能
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

	// 这里就是为了分组,然后再排序执行(规则priority->ordered->nonOrdered)
	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);
		}
	}

	// 执行实现了priority的BFPP
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

	// 执行实现了ordered的BFPP
	List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String postProcessorName : orderedPostProcessorNames) {
		orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

	// 最后执行普通的BFPP
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
	
	beanFactory.clearMetadataCache();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值