文章目录

  • 0、总体的执行流程图
  • 1、测试入口
  • 2、AbstractApplicationContext类的refresh方法
  • 3、PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors方法
  • 4、ConfigurationClassPostProcessor类的processConfigBeanDefinitions方法
  • 5、ConfigurationClassParser类的parse方法
  • 6、ConfigurationClassParser类的processConfigurationClass方法
  • 7、最终的doProcessConfigurationClass方法
  • 8、扫描BD方法doScan

通过本文你将明白:Spring是在代码的什么位置解析@Configuration注解,以及解析@Configuration配置类上面的@ComponentScan注解。整个执行流程中涉及很多的解析细节,本文的讲解仅涉前面的注解内容,其他细节不做过多阐述。


0、总体的执行流程图

1、测试入口

配置类:

@ComponentScan("pers.mobian.springeighth")
@Configuration
public class Config {}

测试类:

public class MainTest {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);}
}

2、AbstractApplicationContext类的refresh方法

调用构造方法,实例化AnnotationConfigApplicationContext类,解析配置注解的位置在refresh方法中。

点开refresh方法,会调用对应的invokeBeanFactoryPostProcessors(beanFactory)方法

3、PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors方法

该方法主要处理两件事情:BD:BeanDefinition

1、处理实现了BeanDefinitionRegisterPostProcess接口的类,调用对应的postProcessBeanDefinitionRegistry方法。

2、处理实现了BeanFactoryPostProcess接口的类,调用对应的postProcessBeanFactory方法。

两者的功能依次为:

1、向Spring的BD集合中添加BD,由于该接口带有注册功能,所以我们可以人为的向向容器中添加BD,(注意区分开,此处添加的是BD,Bean在refresh方法的其他方法中实现)

2、BeanFactory的后置处理器,可对比理解Bean的后置处理器(BeanPostProcess),该接口可完成一些对Bean工厂的逻辑处理

在Spring源码中,第一个含有注册功能的接口实现类为ConfigurationClassPostProcessor类(其余几个类为Spring自带的测试代码)。这个类对应的就是我们的@Configuration注解

下图为该方法的部分执行逻辑:(注意ConfigurationClassPostProcessor类,实现了PriorityOrdered接口)

1、创建一个集合用于存放即将要处理的BeanDefinitionRegistryPostProcessor

2、根据接口类型去获取类

3、校验是否实现了PriorityOrdered接口

4、将数据添加到对应的集合中

5、将集合中的内容进行排序

6、依次执行注册接口对应的方法

4、ConfigurationClassPostProcessor类的processConfigBeanDefinitions方法

在该方法中,Spring会获取我们在实例化AnnotationConfigApplicationContext类时候传入的参数,然后对类进行判断,符合条件的配置类会添加到一个list集合中。在配置类不为空的情况下,会去创建一个ConfigurationClassParser对象,用来解析我们传入的配置类。

图中主要流程为:

1、传入指定的配置类集合,进行解析(解析类上的注解,此处就包括了我们的@ComponentScan注解)

2、对相关内容进行校验

3、通常配置类中还有@Bean定义的Bean、使用@ImportResource导入xml文件中定义的Bean等。调用loadBeanDefinitions方法,就会将这些Bean,添加到BDMap中,在parse方法中也进行了扫描处理,但是那一步仅仅把它们添加到了对应的集合中,没有添加到BDMap中

补充:

此处使用了一个do while循环来处理配置类,而不是直接执行方法,为的是避免我们在解析配置类的时候,可能配置类内部定义的Bean也是一个配置类。只有当我们解析出来的配置类都被解析以后,我们才会真正的跳出循环,即对应配置类的解析操作才算完成

5、ConfigurationClassParser类的parse方法

根据我们传入配置类的不同类型,再调用对应的parse方法

6、ConfigurationClassParser类的processConfigurationClass方法

7、最终的doProcessConfigurationClass方法

该方法中会解析各种注解,其中就包含了我们本次博客的重点@ComponentScan注解

8、扫描BD方法doScan

上一步的parse方法,会调用ComponentScanAnnotationParser类的parse方法,然后调用scanner.doScan(StringUtils.toStringArray(basePackages))方法,完成对应的扫描操作。

在doScan方法中,主要行为为:

1、basePackages:遍历传入进来的路径数组

2、findCandidateComponents:扫描指定路径下所有符合要求的类

3、registerBeanDefinition:将符合要求的类封装成BD的形式,添加到对应的集合中

具体的如何根据路径获取符合要求的类,可以参考我之前的博客:获取指定路径,扫描路径下指定类(仿Spring)

至此,我们的整个解析配置类上的ComponentScan注解的流程就算完毕了。

Spring解析@ComponentScan注解的执行流程相关推荐

  1. Spring MVC开发步骤以及执行流程

    Spring MVC开发步骤以及执行流程 开发步骤 1.在web.xml中定义前端控制器DispatcherServlet来拦截用户请求. 2.如果要以post方式提交请求,则定义包含表单数据的jsp ...

  2. Spring Aop 常见注解和执行顺序

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:juejin.cn/post/7062506923194581029 Spring 一开始最强大的就是 IOC / AOP 两 ...

  3. Spring Security 案例实现和执行流程剖析

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin Spring Security Spring Security 是 Sprin ...

  4. SpringBoot 启动类 @SpringBootApplication 注解 以及执行流程

    @SpringBootApplication  : 是Sprnig Boot项目的核心注解,目的是开启自动配置 目录 @SpringBootApplication  : 是Sprnig Boot项目的 ...

  5. Spring Security 案例实现和执行流程剖析(转)

    本位转自 作者:朝雨忆轻尘 出处:https://www.cnblogs.com/xifengxiaoma/ 文章写的非常好,受益匪浅. Spring Security Spring Security ...

  6. Spring MVC拦截器的执行流程

    本节我们主要讲解 SpringMVC 拦截器的执行流程.分两部分介绍,首先介绍单个拦截器执行流程然后介绍多个拦截器的执行流程. 单个拦截器的执行流程 在配置文件中如果只定义了一个拦截器,程序将首先执行 ...

  7. FlinkSQL源码解析(三)执行流程

    1.前言 前面2部分主要是介绍以下2点: flink sql整体的执行流程大致为:sqlNode --> Operation --> RelNode --> 优化 --> ex ...

  8. Struts 2 Spring Hibernate三大框架的执行流程以及原理

    转:http://www.cnblogs.com/System-out-println/p/5974113.html Struts2框架 一.简介 Struts2是一个相当强大的Java Web开源框 ...

  9. Spring : @ComponentScan注解

    1.美图 2. 源码 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) /

  10. Spring系列(三):@ComponentScan注解用法介绍

    今天给大家分享Spring中@ComponentScan注解的用法,希望对大家能有所帮助! 1.@ComponentScan注解的作用 @ComponentScan注解一般和@Configuratio ...

最新文章

  1. 淘宝2011.9.21校园招聘会笔试题+答案
  2. [计算机网络 谢希仁] 第一章
  3. php ci框架 模板输出,CodeIgniter模板引擎使用实例
  4. 【算法】LeetCode算法题-Maximum Subarray
  5. jQuery 打气球小游戏 点击气球爆炸效果
  6. python 各个模块的简单介绍 转载
  7. 工作分流是什么意思_【嘉陵特装要闻】重庆嘉陵召开持续推进职工分流安置工作布置会...
  8. C语言中字母转换问题
  9. C#通过WebClient/HttpWebRequest实现http的post/get方法
  10. A. 解决运行php文件出现乱码的问题
  11. 10.企业安全建设指南(金融行业安全架构与技术实践) --- 安全预算、总结与汇报
  12. mysql 表继承_如何在数据库中表示继承?
  13. 如何在调试Window App时,触发 Suspending ,Resuming 等事件
  14. 在微型计算机中,ram的特点是___.,2017计算机基础模拟试题「附答案」
  15. 用Linux开发板制作智能音箱,【工程师实战】只要几步,普通音箱秒变小度智能音箱...
  16. ssh: Bad configuration option: usedns
  17. 动态代理—IOC框架
  18. 从pcap文件中解析网络数据包
  19. 计算机c盘属性不显示安全选项,Windows10系统磁盘属性没有安全选项卡(图文)
  20. 魔兽世界服务器响应慢,《魔兽世界》怀旧服排队太慢进不去解决方法

热门文章

  1. 挑战性题目DSCT601:背包问题
  2. lscpu 显示cpu的相关信息
  3. devexpress.xtraeditors.xtraform 类型初始值设定_远程智能电表的常见类型推荐--老王说表...
  4. pythonsuper多重继承_解决python super()调用多重继承函数的问题
  5. 东芝2505扫描软件_如何识别LED显示屏的扫描方式?-美亚迪分享
  6. jdbc map获取keys_小前端读源码 - React(浅析Keys原理)
  7. php反射机制详解,PHP反射机制
  8. securecrt是什么工具_更效率、更优雅 | 阿里巴巴开发者工具不完全盘点
  9. apache ii评分怎么评_APACHEⅡ评分系统
  10. 公钥 私钥_比特币私钥、公钥、钱包地址之间的关系