目的

程序员在对spring扩展的时候,可以自己实现后置处理器,完成特定的业务操作,该篇博客,主要是学习spring如何将程序员提供的后置处理器添加到spring容器中的;
顺带,将spring初始化流程中,其他几个方法做一个大致的解析和介绍

源码学习

registerBeanPostProcessors(beanFactory);

该方法是用来完成,注册BeanPostProcessor实现类的
如果我们自己实现了BeanPostProcessor接口,并提供了自己的业务处理逻辑,spring首先会把我们提供的BeanPostProcessor实现类,在实例化业务bean之前,先实例化,并存入特定的集合中;

org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors

这个方法,就是用来处理后置处理器的
所以:这个方法归结而言,就完成了两件事情

  1. 把所有的BeanPostProcessor(包括spring自己的 + 我们提供的)进行初始化,并存入到spring容器中(signletonObjects这个集合中)
  2. 把所有的BeanPostProcessor存入到一个list中(private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {/*** 1.获取到所有实现了beanPostProcessor接口的实现类的name,从beanDefinitionMaps中获取*  这里在从BeanDefinitionMap中获取BeanPostProcessor类型的实现类的时候,会进行bean的合并,也即:将bean转换Wie*/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.int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest./*** 2.internalPostProcessors:存储的是实现了MergedBeanDefinitionPostProcessor接口的实现类* 这里没想明白为什么要把实现了该接口的实现类单独存储*/List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();/*** 3.按照后置处理器实现的ordered接口 分别存到不同的集合中*/for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {/*** 4.在调用getBean的时候,就会调用对应的初始化方法,完成对beanPostProcessor的初始化*/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(priorityOrderedPostProcessors, beanFactory);/*** 5.registerBeanPostProcessors:该方法,就是把入参中的beanPostProcessor实现类存入到beanPostProcessors这个list集合中*/registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();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);// Now, register all regular BeanPostProcessors.List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

这里的逻辑还是比较简单的,但是与几个点需要注意:

  • 在第一点:从beanDefinitionMap中获取beanPostProcessor的实现类的时候,会对beanDefinition进行一次合并(将beanDefinition合并为RootBeanDefinition,这里的合并bean,在后面的博客中进行说明,这里暂时记一下就好)
  • 在获取到所有的BeanPostProcessor实现类的时候,会对实现类进行优先级的分类,实现了PriorityOrdered > 实现了Ordered > 普通的实现类
  • registerBeanPostProcessors(beanFactory, internalPostProcessors);该方法就是将实例化好的BeanPostProcessor实现类放入到beanPostProcessors这个集合中
  • 在调用getBean()方法的时候,会从单实例池中尝试获取bean,如果bean不存在,就初始化、实例化;也即:在源码中第4点这里,会完成对beanPostProcessor的实例化(意思就是说:经过第4点之后,我们自己提供的beanPostProcessor和spring自己的后置处理器已经走完了整个生命周期流程,是一个合格的bean了)

initMessageSource();

这个方法,暂时还没来得及看,百度了一下,说是用来做国际化、消息绑定等,这里待后面学习之后再补充

initApplicationEventMulticaster();

在这个方法中,初始化了一个多事件派发器ApplicationEventMulticaster,用来做事件发布的

onRefresh();

这是一个扩展方法,在spring framework中是一个空方法,留给子接口进行扩展,其中:springboot启动的源码中,就对该方法做了扩展

registerListeners();

看名字,是用来注册事件监听器的,暂时未学习

finishBeanFactoryInitialization(beanFactory);

这是完成bean实例化的重要方法,在后面会介绍这个方法中的每个核心方法

finishRefresh();

在完成spring的初始化之后,发布ContextRefreshedEvent事件,当然,还有其他的操作,这个方法,也没有做过多的学习,待后面补充吧

接下来,我主要想分享的是finishBeanFactoryInitialization这个方法,这个方法中,是spring将扫描之后的beanDefinition初始化为bean对应,并存入到spring容器中的核心方法

spring源码:注册后置处理器相关推荐

  1. Spring中Bean的后置处理器

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/bean-post-processors.html: Bean后置处理器 BeanPostProce ...

  2. 首发,看了这份美团架构师的spring源码笔记后,才发现原来学习的思路都错了

    前言 Spring让我们可以更快,更轻松,更安全地进行Java编程.Spring对速度,简单性和生产率的关注使其成为世界上最受欢迎的Java框架. 像阿里巴巴,亚马逊,微软等在内的所有科技巨头对Spr ...

  3. spring 源码注册BPP-registerBeanPostProcessors

    上篇传送门 前两篇咱们了解了component-scan和其他一些注解的解析成bean定义信息的过程,前者是通过XML的方式loadBeanDefinition,后者通过ConfigurationCl ...

  4. spring的后置处理器(未完结版)

    学习spring源码也有一阶段时间了,是时候收货的季节了,打算写几篇博客,把自己的知识沉淀下来.在学习spring的源码之前,别人问我spring什么牛逼.我会毫不犹豫的说出AOP,IOC啊.但是看看 ...

  5. Spring之BeanPostProcessor(后置处理器)介绍

      为了弄清楚Spring框架,我们需要分别弄清楚相关核心接口的作用,本文来介绍下BeanPostProcessor接口 BeanPostProcessor   该接口我们也叫后置处理器,作用是在Be ...

  6. 【Spring注解系列11】Spring后置处理器BeanPostProcessor用法与原理

    1.BeanPostProcessor原理 先说,bean的后置处理器BeanPostProcessor接口中两个方法: postProcessBeforeInitialization:在初始化之前工 ...

  7. Spring学习理解---后置处理器

    Spring学习理解之-后置处理器 spring后置处理器有几种?后置处理器的作用 后置处理器有两种: (1)bean的后置处理器:这种处理器会对容器中的bean进行后处理,对bean进行增强 (2) ...

  8. 攀登Spring珠穆朗玛峰:前置与后置处理器

    文章目录 Spring的前置与后置处理器 前提知识 前置与后置处理器定义 前置处理器:BeanFactoryPostProcessor `postProcessBeanFactory`调用 后置处理器 ...

  9. Spring源码(1)

    准备spring环境: @org.junit.Test public void test01(){//把spring所有环境准备好// 1.准备好DefaultListableBeanFactory/ ...

  10. spring--bean后置处理器(BeanPostProcessor)原理解析

    文章目录 功能描述: 如何使用: 定义要处理的接口类型 添加实际需要处理的类 定义后置处理器 编写测试类 执行日志 后置处理器加载解析 registerBeanPostProcessors注册拦截be ...

最新文章

  1. VUE的本地应用-V- show
  2. python openvc 裁剪、剪切图片 提取图片的行和列
  3. Caused by: java.lang.RuntimeException: can not run elasticsearch as root
  4. 有漏洞无作为才可怕、可耻!
  5. 添加组件_Flextools 添加真实凯斯门特双开窗动态组件
  6. Design Pattern - Memento(C#)
  7. 使用RHEL5做NTP服务器出错解决
  8. 羽毛球双打“七宗罪”~很详细!
  9. 封装 js 插件 实例
  10. keepalived(2)——配置文件
  11. Fast R-CNN 个人理解
  12. 【CodeForces - 1051C 】Vasya and Multisets (模拟)
  13. 顺序线性表的基本操作(C语言实现)
  14. linux 外壳的概念,LINUX当中必须知道的概念和小技巧
  15. Array对象的三种属性实例
  16. 手机wap网站制作教程
  17. 蓝桥杯单片机备赛笔记
  18. 嵌入式Linux系统uart串口编程详解及实例分析
  19. 自己来控制EntityFramework4.1 Code-First,逐步消除EF之怪异现象
  20. 贵就好?中消协买20款扫地机器人,艾罗伯特这款噪音大!

热门文章

  1. 算法: 239. 滑动窗口的最大值
  2. 2021-08-30二叉树后向遍历 leetcode 栈
  3. 简述malloc/free与new/delete的区别
  4. Android Studio3.5 JAVA调用C++源码方法总结
  5. JavaWeb请求的重定向与转发:getRequestDispatcher()的forward方法,sendRedirect方法,以及重定向与转发的区别
  6. 数组java8求和_java – 如何使用IntStream对int数组的特定索引号求和?
  7. Prim算法实现最小生成树MST(java)
  8. Spring Cloud随记----远程配置文件资源库的建立-涉及一些简单的git操作
  9. 使用梯度下降与牛顿法求解最小平方和问题
  10. 能力提升综合题单Part 8.2 最短路问题