【spring学习笔记 四】registerBeanPostProcessors()

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

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

上一篇我们聊完了注册与唤醒BeanFactoryPostProcessor,这篇我们就来聊聊BeanPostProcessor的注册 。

registerBeanPostProcessors()

第一步:添加BeanPostProcessorChecker

创建BeanPostProcessorChecker有两个参数一个beanFactory,一个就是count。
而这个count就代表了当前环境中应该有BeanPostProcessor个数。

BeanPostProcessorChecker作用就是记录加载的BenPostProcessor的日志。 比较简单

		//找到beanFactory中所有的BeanPostProcessor名称
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
		//已存在的BeanPostProcessor个数+自己+注册的BeanPostProcessor
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

第二步:对BeanPostProcessor的实现类进行排序

也就是上一张针对BeanFactoryPostProcessor排序一样,不过这里还有点特殊的地方。

		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();//优先队列
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();//新增一个,主要处理Bean内部的一些情况(@Value,@AutoWrite类似的)
		List<String> orderedPostProcessorNames = new ArrayList<>(); //排序队列
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();//普通队列
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

这里可以看到分为了4个集合,分别是:

  1. 实现了PriorityOrdered的优先队列
  2. 实现了MergedBeanDefinitionPostProcessor的bean定义合并队列
  3. 实现了Ordered的排序队列
  4. 什么都没有的普通队列

注册顺序分别为 1,3,4 。
这里细心的同学可能已经发现了,上面的代码中只有满足PriorityOrdered的条件才会判断MergedBeanDefinitionPostProcessor。那么是不是意味着必须要实现PriorityOrdered呢?
答案当然是否定的,在后面处理其它两类队列的时候会进行判断。这样在MergedBeanDefinitionPostProcessor维度也有了顺序。

第三步:注册优先队列

		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); 

第四步:注册排序队列

		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors); 

第五步:注册普通队列

		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

第六步:注册实现了MergedBeanDefinitionPostProcessor的队列

		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

第七步:注册ApplicationListenerDetector

		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

ApplicationListenerDetector这个类的作用就是找出所有Bean中实现了ApplicationListener的单例,并将其放入容器的Listener集合中。这也是自定义Listener的第二种方法(不过这一类的Listener对于比较靠前的事件是监听不到的)。

MergedBeanDefinitionPostProcessor

MergedBeanDefinitionPostProcessor是一种继承BeanPostProcessor的特殊扩展点。

它赋予了开发者在创建Bean之前对Bean的创建模板进行一定的修改。

比如说大家比较熟悉的@Autowrited 自动装配这个注解。
它的处理类AutowiredAnnotationBeanPostProcessor就实现了 MergedBeanDefinitionPostProcessor 。
主要的作用就是将那些需要被装配的属性放入BeanDefinition供后续填充的时候使用(填充会在后面的章节getBean中详细讲解)。

还有一个就是@Resource 这个注解
它的处理CommonAnnotationBeanPostProcessor处理的思路跟上面的是基本相同的。

其它的我就不一一列举了,只要是跟Bean创建过程中属性或方法的填充,解决方案多半都与MergedBeanDefinitionPostProcessor 有关。

总结

我们接下来总结下注册BeanPostProcessor的流程

  1. 添加一个日志记录处理器
  2. 将BeanPostProcess进行排序
  3. 按照顺序注册BeanPostOProcessor
  4. 添加一个处理ApplicationListener的处理器

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

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

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

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