目的

从扫描bean的原理 到 @Configuration源码
这之间的几篇关于spring源码的博客,都是围绕着一个方法来解析的

invokeBeanFactoryPostProcessors(beanFactory);
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors

所以,打算在这篇博客中,对这个方法做一个小总结

  1. 在进入到该方法的时候,首先会执行程序员通过api(ac.addBeanFactoryPostProcessor();)注入的BeanFactoryPostProcessor的实现类(这里需要注意:如果一个类实现了BeanFactoryPostProcessor或者实现了BeanDefinitionRegistryPostProcessor接口,我们都可以称之为BeanFactoryPostProcessor的实现类)
  2. 会先执行上面第一步注入的BeanFactoryPostProcessor的子接口BeanDefinitionRegistryPostProcessor对应的实现类,此时,执行的就是程序员自己实现的业务逻辑代码,但是这种场景应该会比较少吧,因为毕竟这时候,连bean都还没有扫描到beanDefinitionMap中,但是既然spring提供了响应的扩展点,总归是会有用到的场景
  3. 如果程序员没有通过api提供实现类,那么会从beanDefinitionMap中获取BeanDefinitionRegistryPostProcessor的实现类。理论上而言,这时候,只会获取到一个,就是ConfigurationClassPostProcessor,这里原因就不解释了,在前面的博客中有说到过
  4. 会先执行org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry 在这里,完成了对bean的扫描(@ComponentScan注解、@Bean、@Import注解),这个方法执行完之后,会把程序员提供的业务类扫描到beanDefinitionMap中
  5. 在将业务bean扫描到beanDefinitionMap中之后,会从beanDefinitionMap中获取BeanDefinitionRegistryPostProcessor的实现类,会按照以下优先级,先后执行,实现了PriorityOrdered > 实现了 Ordered > 普遍的BeanDefinitionRegistryPostProcessor实现类;这里为什么要这么做?因为有可能程序员自己也提供了BeanDefinitionRegistryPostProcessor或者BeanFactoryPostProcessor的实现类;所以,要扫描执行程序员提供的业务逻辑
  6. 执行完BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法之后,接着要执行BeanFactoryPostProcessor的postProcessBeanFactory方法
  7. ①、先执行spring内置的、通过注解注入的、通过API注入的,BeanDefinitionRegistryPostProcessor实现类中对应的postProcessorBeanFactory方法(因为一个实现类,实现BeanDefinitionRegistryPostProcessor的方法时,必然要实现BeanFactoryPostProcessor接口中的方法)
    ②、再执行程序员通过API的方式注入的BeanFactoryPostProcessor实现类对应的postProcessorBeanFactory方法
    ③、执行程序员通过注解方式注入的BeanFactoryPostProcessor的实现类;按照以下优先级先后执行:实现了PriorityOrdered接口的实现类先执行 > 实现了Ordered接口的实现类先执行 > 普通的BeanFactoryPostProcessor实现类最后执行

上面的这个流程中,在第7.①、这里,执行到ConfigurationClassPostProcessor的postProcessBeanFactory方法的时候,会对全配置类(加了@Configuration)生成代理对象

所以,在spring源码中的这一步,就是对org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory 和 org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry这两个接口的实现类的处理,只是在处理的时候,会有先后的顺序,接口实现类有执行的先后顺序,程序员提供的扩展类和spring内置的实现类有先后的执行顺序,所以,大体上,要先把执行时机和顺序理清楚,然后再一步一步扣每个方法的细节

所以,对于BeanFactoryPostProcesosr和BeanDefinitionRegistryPostProcessor的执行先后顺序,我也整理了一下:

1.首先执行BeanDefinitionRegistryPostProcessor的实现类1.1 首先执行程序员通过API的方式注入的BeanDefinitionRegistryPostProcessor实现类1.2 再执行spring内置的ConfigurationClassPostProcessor对应的postProcessorBeanDefinitionRegistry方法1.3 执行程序员通过@Component注解方式注入的BeanDefinitionRegistryPostProcessor的实现类1.3.1 实现了PriorityOrdered接口的实现类先执行1.3.2 其次是实现了Order接口的1.3.3 最后会通过一个while循环,处理所有普通的BeanDefinitionRegistryPostProcessor的实现类,直到beanDefinitionMap中不存在未处理的BeanDefinitionRegistryPostProcessor的实现类2.其次执行BeanFactoryPostProcessor的实现类2.1 先执行spring内置的、通过注解注入的、通过API注入的,BeanDefinitionRegistryPostProcessor实现类中对应的postProcessorBeanFactory方法(因为一个实现类,实现BeanDefinitionRegistryPostProcessor的方法时,必然要实现BeanFactoryPostProcessor接口中的方法);在这里,spring把beanDefinitionRegistryPostProcessor的实现类中的postProcessorBeanFactory()放在了一起来执行2.2 再执行程序员通过API的方式注入的BeanFactoryPostProcessor实现类对应的postProcessorBeanFactory方法(需要注意这里和2.1的区别,举个例子:如果我自己声明了A类,实现了BeanDefinitionRegistryPostProcessor实现类;声明了B类,实现了BeanFactoryPostProcessor接口;那么:A类和B类中的postProcessorBeanFactory()方法都会被执行,只是A类中的方法是在2.1执行的,B类中的是在2.2或者2.3这里)2.3 执行程序员通过注解方式注入的BeanFactoryPostProcessor的实现类2.3.1 实现了PriorityOrdered接口的实现类先执行2.3.2 实现了Ordered接口的实现类先执行2.3.3 普通的BeanFactoryPostProcessor实现类最后执行

spring扫描bean总结相关推荐

  1. 源码解读 Spring中Bean扫描的原理

    前言. Spring和MyBatis整合的时候用到的Bean扫描是它Spring本身提供的.这一篇文章就写一下Spring是如何实现Bean扫描的. 不得不说Bean扫描是一个很重要的技术,在Spri ...

  2. Spring 注解 @bean 和 @component 的区别, 你知道吗?

    本文打算介绍几个不太容易说出其区别,或者用途的 Spring 注解,比如 @Component 与 @Bean 的比较,@ControllerAdvice 是如何处理自定义异常的等等. Spring ...

  3. 面试官:讲讲Spring框架Bean的加载过程

    spring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典.优秀的框架,它的复杂程度往往令人望而却步. 不过作为朝夕相处的框架,我们必须得明白一个问题就是spri ...

  4. spring --(12)bean的生命周期

    2019独角兽企业重金招聘Python工程师标准>>> springIOC容器可以管理bean的生命周期,管理过程: 1>通过构造器或工厂方法创建bean实例 2>给be ...

  5. spring boot实战(第十篇)Spring boot Bean加载源码分析

    前言 前面的文章描述了Application对应Bean的创建,本篇将阐述spring boot中bean的创建过程 refresh 首先来看SpringApplication#run方法中refre ...

  6. spring扫描自定义注解并进行操作

    今天又个需求,就是根据注解来判断是否接口为对外开放,那么启动spring容器的时候把这些注解修饰的bean name放进缓存当中. /**  * 扫描注解添加服务到缓存以供判断时候为对外开放servi ...

  7. (转)Spring中Bean的命名问题(id和name区别)及ref和idref之间的区别

    Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...

  8. Spring 管理Bean(获取Bean,初始化bean事件,自动匹配ByName······等)

    1.实例化spring容器 和 从容器获取Bean对象 实例化Spring容器常用的两种方式: 方法一: 在类路径下寻找配置文件来实例化容器 [推荐使用] ApplicationContext ctx ...

  9. 厉害了,Spring中bean的12种定义方法!

    前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...

  10. Spring Boot文档阅读笔记-Spring Boot @Bean解析

    利用SpringBoot的@Bean创建一个简单的Bean. Spring的@Bean注解是放在方法上的,带上这个注解的方法会被Spring容器管理.并且这个方法要返回一个值(对象),这个值和对象会被 ...

最新文章

  1. LeetCode简单题之有效的字母异位词
  2. Delphi 正则表达式之TPerlRegEx 类的属性与方法(3): Start、Stop
  3. 攻防世界-Misc-something_in_image(秒懂!!)
  4. 机器学习与气象数据_气象大数据与机器学习联合实验室 大数据和气象的“联姻”...
  5. 如何把开源项目发布到Jcenter
  6. perf-perf stat用户层代码分析
  7. 云计算商家必争之地 推荐几款云平台
  8. WinAPI: waveInGetPosition - 获取当前输入设备的输入位置
  9. Java语言程序设计(一)填空题
  10. python全栈 操作系统
  11. 趣味程序之打印字符图案系列
  12. configure: error: C++ compiler cannot create executables
  13. 用nmap扫描内网conficker
  14. Spark独到见解--3控制算子
  15. 80004005错误代码_0x80004005,手把手教你解决0x80004005错误代码的方法
  16. Kibana关联ES查询数据
  17. 上拉电阻的作用原理_单片机P0口以及上拉电阻
  18. 我用Python实现自动化办公,美女同事投来羡慕的眼神,而后···
  19. Spacy model download
  20. 本科毕设论文如何写(1)-- 快速下手

热门文章

  1. 翻译: TensorFlow 2.0 中的符号和命令式 API 是什么?
  2. 易筋SpringBoot 2.1 | 第九篇:SpringBoot使用Redis内存数据库
  3. 2021-10-25双塔模型
  4. 8. 字符串转整数 (atoi)
  5. hadoop2.8配置_hadoop2.8安装教程
  6. Numpy快速入门教程
  7. 【ACM ICPC 2011–2012, Northeastern European Regional Contest】Interactive Permutation Guessing【交互题】
  8. TIG:一款威胁情报收集小工具
  9. 345.反转字符串中的元音字符(力扣leetcode) 博主可答疑该问题
  10. python同名函数相互冲突_两个函数同名python