可能是最卷的Spring源码系列(七):BeanFactoryPostProcessors源码分析

BeanFactoryPostProcessors调用时机

前面的文章讲到通过BeanFactoryPostProcessors来扩展spring的方法,那么BeanFactoryPostProcessors究竟是什么时候执行到的呢?本文会通过分析容器的初始化流程来讲到BeanFactoryPostProcessors的调用的时机

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);

这么一行代码即完成了容器的初始化,之后便可以对容器进行使用,这一行代码的底层完成了哪些复杂的操作呢?
我们先点进构造方法
在这里插入图片描述

this()方法详解

在这里插入图片描述

前面文章总结过这部分的执行过程,此处只做简单的总结
这里面实例化了两个对象 reader 和 scanner
reader 作用:
1、把context.register()的类变成BD,并放入容器
2、把几个固定的postProcessor包装成BD,并放入容器
scanner作用:
1、context.scan() 对指定包进行扫描
2、被继承进行个性化扫描,其中ConfigurationClassPostProcessor中实现了个性化扫描

this.register(annotatedClasses)方法详解

在这里插入图片描述
最终由这个方法进行执行,主要的作用就是创建了一个BD,然后注册到容器中去

this.refresh()方法详解

这个是一个关键的方法,spring容器的初始化都是在这里完成的

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			// 对AbstractApplicationContext中使用到的组件进行初始化
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 获取到beanFactory,这个beanFactory是在AbstractApplicationContext子类的中创建的,这时候拿出来是在AbstractApplicationContext类可以用
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 执行了beanFactory中的一些方法,为了对beanFactory和用到的组件初始化
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 这个方法没实现,是要交给子类实现的,AnnotationConfigApplicationContext也没实现
				// 其他子类有实现的,看注释意思为允许对beanFactory后置处理,应该是为下一步做的基本操作
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 执行beanFactory后置处理
				// 包含BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册beanPostProcessors  把bdMap中的beanPostProcessors注册到
				// 两种方式注册BeanPostProcessors
				// 1、beanFactor.addBeanPostProcessor 注册到beanFactor.beanPostProcessors
				// 2、注册进bdMap的BeanPostProcessor
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 国际化用的
				initMessageSource();

				// Initialize event multicaster for this context.
				// 事件相关的
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 这个方法没实现,是要交给子类实现的,初始化特殊的bean,AnnotationConfigApplicationContext没实现
				onRefresh();

				// Check for listener beans and register them.
				// 也是事件相关的
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 实例化在这里完成
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

我们重点看invokeBeanFactoryPostProcessors方法,BeanFactoryPostProcessors就是在这里执行完的,我们可以先简单的分析一下
invokeBeanFactoryPostProcessors执行之前都是容器的初始化方法,就是对容器中的一些组件进行初始化,可以认为都是一些无关紧要的事情,这么看来容器做的第一件重要的事情就是invokeBeanFactoryPostProcessors,那么为什么要把invokeBeanFactoryPostProcessors放在第一位来完成呢?
我们根据BeanFactoryPostProcessors的作用就可以知道,BeanFactoryPostProcessors是对容器进行增强的,所以要放在最开始执行,之后才能执行bean有关的操作,如果放在bean后面执行,那就达不到想要的效果了。
我们来看代码
在这里插入图片描述
这里有一个需要注意的点,看到这里传进来了两个参数,一个是容器本事,一个是通过getBeanFactoryPostProcessors获取到的BeanFactoryPostProcessors列表,这个列表中存放着通过AnnotationConfigApplicationContext#addBeanFactoryPostProcessor注册进来的BeanFactoryPostProcessors,除了这种方法,还能通过往容器中添加BD,BD的class是BeanFactoryPostProcessors的方法进行注册,那样的话就会注册到bdmap中
为什么要有这两种方式呢?暂时还没有找到原因,如果你知道其中的原因,欢迎留言讨论。
继续往后跟
在这里插入图片描述
这个方法最终完成了BeanFactoryPostProcessors的调用

BeanFactoryPostProcessors调用顺序

我认为invokeBeanFactoryPostProcessors里面最重要的逻辑就是分批调用,为什么分批调用?我认为有两个原因,如果不准确欢迎留言讨论
1、有些BeanFactoryPostProcessors需要顺序执行
2、为了区分BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor

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

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		// 这个集合用来保存执行完的processedBeans,为什么要存储执行完的?
		// 递归执行的时候防止重复
		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<>();
			// 执行所有通过content.addBeanFactoryPostProcessor注册进来的PostProcessor 这种PostProcessor不进BDMap,不进单例池
			// 如果是BeanDefinitionRegistryPostProcessor,立刻执行postProcessBeanDefinitionRegistry方法,并存processedBeans和registryProcessors中
			// 如果是BeanFactoryPostProcessor 直接存储到regularPostProcessors中
			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.
			// 为了分批执行创建的,一次执行一批,把每一批放这个里面
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 取出来容器中BDMap中的所有BeanDefinitionRegistryPostProcessor
			// 这里通常只有一个ConfigurationClassPostProcessor,它完成了扫描
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			// 这里完了扫描 这里的扫描是指解析配置类(解析配置类中的各种注解)
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			/**
			 * 下面又获取并执行了1+n遍BeanDefinitionRegistryPostProcessor,因为上一步会扫描进来BD
			 * 为什么获取了1+n遍?
			 * 第一遍是执行了所有实现了Ordered的BeanDefinitionRegistryPostProcessor(去掉上面执行完的)
			 * 其余的n编执行了剩余的所有Ordered的BeanDefinitionRegistryPostProcessor
			 * 因为每一次执行都可能有新的BeanDefinitionRegistryPostProcessor进来,所以执行n编
			 */

			// 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);
			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的postProcessBeanFactory接口
			// 执行BeanFactoryPostProcessor(只包含content.addBeanFactoryPostProcessor进来的)的postProcessBeanFactory接口
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			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 这个地方不用递归是因为这个时候已经不能注册BD了,BDMap里面不会有新增的BeanFactoryPostProcessor
		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(不包含content.addBeanFactoryPostProcessor进来的)分类
		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);
			}
		}
		// 分三类执行
		// 1、实现了PriorityOrdered的
		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 2.实现了Ordered并且没实现Ordered的
		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 3、没实现PriorityOrdered和Ordered的
		// Finally, invoke all other BeanFactoryPostProcessors.
		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进行一下分类
第一类:不进bdmap的BeanFactoryPostProcessor
第二类:进bdmap的BeanFactoryPostProcessor
第三类:不进bdmap的BeanDefinitionRegistryPostProcessor
第四类:进bdmap的BeanDefinitionRegistryPostProcessor
还有一个分类维度是是否添加了顺序注解的,我们就不放在大类里面进行区分

最后我们总结一下BeanFactoryPostProcessor的调用顺序
1、执行第三类
2、执行第四类中实现PriorityOrdered接口的,但是当前只会有一个ConfigurationClassPostProcessor,它完成了扫描
3、执行第四类所有实现了Ordered的BeanDefinitionRegistryPostProcessor
4、递归执行第四类所有没实现Ordered的和步骤二、三中扫描出来的BeanDefinitionRegistryPostProcessor
————————————————————————————
以上执行的都是postProcessBeanDefinitionRegistry方法
————————————————————————————
以下执行的都是postProcessBeanFactory方法
————————————————————————————
5、执行第一类、第三类的postProcessBeanFactory方法
6、执行第二类、第四类中实现PriorityOrdered注解的
7、执行第二类、第四类中实现Ordered并且没实现PriorityOrdered的
8、执行第二类、第四类中没实现Ordered并且没实现PriorityOrdered的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值