接下来我们继续探索registerBeanPostProcessors的用法。这里需要注意的是,注册拦截Bean创建的Bean处理器,这里只是注册,真正的调用是在getBean时候。(相关资源可到这里下载:http://pan.baidu.com/s/1sjSo9a9)

1. PostProcessorRegistrationDelegate

在AbstractApplicationContext类中,调用函数registerBeanPostProcessors,而这个函数又调用了类PostProcessorRegistrationDelegate中的registerBeanPostProcessors这个函数。所以我们的重心就是在这里分析了。

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// Register BeanPostProcessorChecker that logs an info message when// a bean is created during BeanPostProcessor instantiation, i.e. when// a bean is not eligible for getting processed by all BeanPostProcessors.//BeanPostProcessorChecker是一个普通的信息打印,可能会有些情况//当Spring的配置中的后处理器还没有被注册就已经开始了bean的初始化//便会打印出BeanPostProcessorChecker中设定的信息。int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.//使用PtiorityOrdered保证顺序List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();//使用Ordered保证顺序List<String> orderedPostProcessorNames = new ArrayList<String>();//无序BeanPostProcessorList<String> nonOrderedPostProcessorNames = new ArrayList<String>();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);}}// First, register the BeanPostProcessors that implement PriorityOrdered.sortPostProcessors(beanFactory, priorityOrderedPostProcessors);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}sortPostProcessors(beanFactory, orderedPostProcessors);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// Now, register all regular BeanPostProcessors.List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// Finally, re-register all internal BeanPostProcessors.sortPostProcessors(beanFactory, internalPostProcessors);registerBeanPostProcessors(beanFactory, internalPostProcessors);beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}

在函数的调用中,可能读者会认为对于internalPostProcessons中存储的后处理器也是MergedBeanDefinitionPostProcessor类型的处理器,在代码中似乎是被重复调用了,其实是不然,我们可以看registerBeanPostProcessor方法的实现。

private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {for (BeanPostProcessor postProcessor : postProcessors) {beanFactory.addBeanPostProcessor(postProcessor);}}

2. AbstractBeanFactory

我们通过最后的registerBeanPostProcessors的函数并没有得不到我们提出的疑问,别急,我们继续看一下addBeanPostProcessor的函数。分析一个问题的答案就出来了。

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");this.beanPostProcessors.remove(beanPostProcessor);this.beanPostProcessors.add(beanPostProcessor);if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {this.hasInstantiationAwareBeanPostProcessors = true;}if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {this.hasDestructionAwareBeanPostProcessors = true;}}

Spring源码之ApplicationContext(六)注册BeanPostProcessor相关推荐

  1. 第五篇:Spring源码篇-ApplicationContext

    Spring源码篇-ApplicationContext   前面通过手写IoC,DI.AOP和Bean的配置.到最后ApplicationContext的门面处理,对于Spring相关的核心概念应该 ...

  2. Spring源码之ApplicationContext

    ​ 本文是针对Srping的ClassPathXMLApplicationContext来进行源码解析,在本篇博客中将不会讲述spring Xml解析注册代码,因为ApplicationContext ...

  3. Spring源码之Bean的注册(使用XML配置的方式)

    本文分析的Spring源码是5.2.2版本,使用Gradle进行管理. 一.Bean的注册,先来看通过XML配置Bean的方式 1.配置applicationContext.xml: <?xml ...

  4. Spring源码解析-applicationContext.xml加载和bean的注册

    applicationContext文件加载和bean注册流程 ​ Spring对于从事Java开发的boy来说,再熟悉不过了,对于我们这个牛逼的框架的介绍就不在这里复述了,Spring这个大杂烩,怎 ...

  5. Spring源码阅读(六)

    这一讲分析spring bean属性注入代码populateBean,源码分析如下 /*** Populate the bean instance in the given BeanWrapper w ...

  6. Spring源码之Bean的注册(注解方式)

    1.创建AnnotationConfigApplicationContext AnnotationConfigApplicationContext context = new AnnotationCo ...

  7. 【06】Spring源码-分析篇-ApplicationContext

    Spring源码篇-ApplicationContext   前面通过手写IoC,DI.AOP和Bean的配置.到最后ApplicationContext的门面处理,对于Spring相关的核心概念应该 ...

  8. beanfactorypostprocessor_Spring源码分析(六)容器的扩展点(BeanFactoryPostProcessor)

    之前的文章我写了BeanDefinition的基本概念和合并,其中很对次提到了容器的扩展点,这篇文章就写这方面的知识.这部分的内容主要涉及到官网的1.8小节.按照官网介绍来说,容器的扩展点可以分为三类 ...

  9. Spring源码——容器扩展ApplicationContext

    前言 内容主要参考自<Spring源码深度解析>一书,算是读书笔记或是原书的补充.进入正文后可能会引来各种不适,毕竟阅读源码是件极其痛苦的事情. 本文主要涉及书中第六章的部分,依照书中内容 ...

  10. Spring源码-AOP(六)-自动代理与DefaultAdvisorAutoProxyCreator

    2019独角兽企业重金招聘Python工程师标准>>> Spring AOP 源码解析系列,建议大家按顺序阅读,欢迎讨论 Spring源码-AOP(一)-代理模式 Spring源码- ...

最新文章

  1. Boosting、Adaboost、AdaBoost模型的优缺点、提升树、梯度提升树GBDT
  2. Oracle 11G在用EXP 导出时,空表不能导出解决
  3. 开学前要多为孩子健康做准备
  4. treeview右键添加新节点
  5. 【Vegas原创】ASP 0131 不允许父路径的解决
  6. linux wenj 立即生效_【新书连载】测试工程师核心开发技术(3)—远程登录Linux系统...
  7. 【牛客 - 551F】CSL 的神奇序列(推公式,猜结论,母函数)
  8. Vue.js 第二天: 事件处理
  9. apache http server 停止工作_Tomcat9配置HTTP/2
  10. css3中的box-sizing的用法
  11. 一个借口几万条数据但是只返回十条_爬虫实践之爬取10000条菜谱数据
  12. 宗地图绘制要求和规范_宗地图绘制的基本要求与内容.ppt
  13. 如何通过官方原版win10PE安装纯净版win10系统
  14. 菊花是哪个城市的市花1_2.html,花中四君子——秋菊知多少?
  15. 各大城市值得加入的互联网公司有哪些?
  16. c语言实现姓名排序———字符串复制函数,字符串比较函数
  17. nvidia windows linux,不逊于Win7,英伟达Linux版显卡驱动稳定版下载
  18. 密评复习(选择+简答)
  19. 毕业论文管理系统的设计与实现
  20. BP神经网络实现汽油辛烷值预测,《MATLAB源码+数据集》

热门文章

  1. 51nod 1106 质数检测
  2. HPU--1392 分隔A+B
  3. openstack排错
  4. iOS 创建单例的方法
  5. (转)C++类所占内存大小计算
  6. Bran的内核开发指南_中文版
  7. 腾讯新浪通过IP地址获取当前地理位置(省份)的接口
  8. Linux之LVM(逻辑卷管理)、分层存储Stratis、VDO、SWAP分区及相应案例
  9. php数组操作,内容相同,键值不同,互换
  10. Hibernate学习(一)创建数据表