【spring学习笔记 三】invokeBeanFactoryPostProcessors()

导读:本篇文章讲解 【spring学习笔记 三】invokeBeanFactoryPostProcessors(),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,原文地址:Java

也许你感觉自己的努力总是徒劳无功,但不必怀疑,你每天都离顶点更进一步。今天的你离顶点还遥遥无期。但你通过今天的努力,积蓄了明天勇攀高峰的力量。加油!

上篇交代了refresh()的整个流程,下面我们就来看看其中比较重要的流程invokeBeanFactoryPostProcessors()。

这个方法主要是唤醒BeanFactoryPostProcessor和其子类BeanDefinitionRegistryPostProcessor

invokeBeanFactoryPostProcessors()

顾名思义,就是唤醒BeanFacotryPostProcessor的所有实现,我们先来看看它内部的流程。

由于里面的代码比较多,有些思路比较重复。所以我就对它进行分块说明

好了,整体逻辑梳理出来了。接下来我们看下详细步骤:

这里说明下BeanDefinitionRegistryPostProcessor 继承自BeanFactoryPostProcessor

第一步:处理spring自带的一些BeanFactoryPostProcessor

如果实例只实现BeanFactoryPostProcessor,就将其加入到集合中等后面在执行。
如果实例BeanDefinitionRegistryPostProcessor则唤醒其方法。

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

其每个实例具体作用,先自行研究。如果后面有机会的话在进行分享。

第二步:处理BeanFactory中注册的BeanDefinitionRegistryPostProcessor

这一步非常重要,因为这一步涉及到一个类,这个类就叫做ConfigurationClassPostProcessor,在BeanFactory里面的名称是org.springframework.context.annotation.internalConfigurationAnnotationProcessor。

为什么说它重要呢,因为这个类的工作就是通过扫描路径,找到所有@Component,@Service,@Controller等(眼熟把,就是通过这个类进行加载的。)并将其注册到BeanFactory中,非常关键的一个类。

			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);
			//唤醒,到目前为止registryProcessors中的所有实例都已经被唤醒过了。
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

第三步:再次从BeanFactory中取出BeanDefinitionRegistryPostProcessor并处理

当然,处理过的是不会在处理了。为什么要这么做呢? 因为有可能上面被唤醒的实例继续注册BeanDefinitionRegistryPostProcessor(因为这个接口就是registry流程的前置接口),所以又去取一遍,继续唤醒。

			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(); 

第四步:循环从BeanFactory中取出BeanDefinitionRegistryPostProcessor并处理

聪明的同学这时候可能已经想到了,那不就是可以无限套娃了嘛。。。
所以最后还有一个循环,一直到取不到BeanDefinitionRegistryPostProcessor为止。
为什么第三步不这样做? (没想明白)

			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.
			//唤醒上面所有BeanDefinitionPostProcessor的PostProcessorBeanFactory方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

第五步:将spring自带的BeanFactoryPostProcessor唤醒

在第一步的时候我们只处理了BeanDefinitionRegistryPostProcessor,现在是时候将剩下的一部分BeanFactoryPostProcessor给唤醒了。

			//这个集合里面放着的就是上面(ApplicationContext中)实现了BeanFactoryPostProcessor的但是没继承它的子类BeanDefinitionPostProcessor
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

第六步:唤醒BeanFactory里面所有的BeanFactoryPostProcessor

上面的几步我们几乎全是处理的BeanDefinitionRegistryPostProcessor,所以从这一步开始我们将唤醒BeanFactoryPostProcessor(当然,上面唤醒过的BeanDefinitionRegistryPostProcessor会被排除掉)。

下面这几步几乎都是一个模板,

  1. 类是否实现了PriorityOrdered(优先级最高)
  2. 类是否实现了Ordered(排序)
  3. 什么都没有实现(普通)
  4. 按照优先级进行唤醒
		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<>(orderedPostProcessorNames.size());
		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<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

总结

  1. 唤醒spring自带的BeanDefinitionRegistryPostProcessor
  2. 通过BeanFactory获取BeanDefinitionRegistryPostProcessor并唤醒(主要是与环境相关的,其中最重要的ConfigurationClassPostProcessor)
  3. 继续通过BeanFactory获取BeanDefinitionRegistryPostProcessor并唤醒(因为上一步加载了很多类到BeanFactory中)
  4. 继继续通过BeanFactory获取BeanDefinitionRegistryPostProcessor并唤醒(同样,可能上一步加载了很多类到BeanFactory中)
  5. 套娃模式开启!通过BeanFactory获取BeanDefinitionRegistryPostProcessor直到没有为止(同样,可能上一步加载了很多类到BeanFactory中)
  6. 处理第一步遗留的BeanFactoryPostProcessor
  7. 通过BeanFactory获取BeanFactoryPostProcessor
  8. 排序并唤醒

到这里invokeBeanFactoryPostProcessors()就分析完毕了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/121871.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!