概述

  • 这里主要分析@Configuration注解的类自身的加载的实现,即生成该类对应的BeanDefinition,注册到BeanFactory,此时该类就跟一个普通使用了如@Component注解的类一样,是在创建和初始化BeanFactory的过程中完成的。而@Configuration注解的处理是通过ConfigurationClassPostProcessor来完成的,ConfigurationClassPostProcessor是一个BeanFactoryPostProcessor接口实现类。
  • 以下先从我们熟悉的@Configuration注解的处理实现说起,然后再回过头来分析在执行@Configuration的注解处理之前,@Configuration注解的类是怎么注册到BeanFactory中的。通俗来说,就以先分析怎么煎鸡蛋,再分析这个鸡蛋怎么被母鸡生出来的思路来分析。

@Configuration的注解处理器ConfigurationClassPostProcessor的创建

  • AnnotationConfigBeanDefinitionParser是<context:annotation-config />的标签处理器。
  • AnnotationConfigBeanDefinitionParser会调用AnnotationConfigUtils.registerAnnotationConfigProcessors方法;
  • 如果Spring容器所使用的ApplicationContext接口实现类为AnnotationConfigApplicationContext,则也会调用这个方法。
  • AnnotationConfigUtils.registerAnnotationConfigProcessors方法的执行,会注册三个注解处理器,分别是:
    1. ConfigurationClassPostProcessor:BeanFactoryPostProcessor接口的实现类,处理@Configuration,@Component,@ComponentScan,@Import,@ImportResource或@Bean注解。
    2. AutowiredAnnotationBeanPostProcessor:BeanPostProcessor接口实现类,处理@Autowired注解。
    3. CommonAnnotationBeanPostProcessor:BeanPostProcessor接口实现类,处理JDK提供的注解,如@PostConstruct,@PreDestroy,@Resource等。
    4. PersistenceAnnotationBeanPostProcessor(使用JPA的时候)

@Configuration注解的类的加载

  • ConfigurationClassPostProcessor为BeanFactoryPostProcessor,此时是从BeanFactory获取已经创建好的BeanDefinition,检测每个BeanDefinition对应的类上面是否使用了以上四个注解。所以在基于注解的配置设计中,对应的类怎么才能生成对应的BeanDefinition注册到BeanFactory,之后才能被ConfigurationClassPostProcessor处理?如果是基于XML的,一般会在applicationContext.xml中通过<context:component-scan />注解或者bean标签,获取到了相关的BeanDefinition。
  • 其实@Configuration注解的作用是作为一个配置类,对应类内部使用@Bean注解方法,则该方法会作为BeanDefinition注册到BeanFactory中。以及扫描一起使用的@ComponentScan注解指定的类或包,获取对应的BeanDefinition。
Spring容器ApplicationContext
  • 但是对于Spring容器而言,即ApplicationContext接口的实现类,既可以是基于XML的XmlApplicationContext,即使用applicationContext.xml来作为配置,也可以是基于JavaConfig,如实现WebApplicationInitializer接口,在这个接口的onStartup方法中,指定特定的ApplicationContext,一般为AnnotationConfigApplicationContext,并指定使用了@Configuration注解的配置类,作为AnnotationConfigApplicationContext的构造函数参数值。所以针对这两种方式,分别说明如何使@Configuration注解的类,先作为BeanDefinition注册到BeanFactory,然后再被ConfigurationClassPostProcessor处理其上的注解。

    1. 基于applicationContext.xml:使用<context:component-scan />标签,并在base-package属性指定的@Configuration类所在的包,则Spring容器启动时,就会加载@Configuration注解类并创建BeanDefinition对象注册到BeanFactory中,之后ConfigurationClassPostProcessor作为BeanFactoryPostProcessor,从BeanFactory取出并赛选使用了@Configuration注解的类对应的的BeanDefinition,处理其上的@ComponentScan等注解和类内部使用@Bean注解的方法。
    2. 基于JavaConfig的方式,在WebApplicationInitializer接口实现类的onStartup方法中,以@Configuration注解的类作为构造函数参数,创建AnnotationConfigApplicationContext对象,然后交给该对象以attribute方式添加到ServletContext中。此时AnnotationConfigApplicationContext在内部会使用AnnotatedBeanDefinitionReader注册这个使用了@Configuration注解的配置类到BeanFactory中。之后ConfigurationClassPostProcessor完成与基于applicationContext.xml的方式中一样的处理。
    3. SpringBoot的处理方式:SpringBoot的SpringApplication使用AnnotationConfigApplicationContext作为Spring容器的ApplicationContext,然后将main方法所在启动类作为参数调用SpringApplication.run方法,其中该启动类为一个基于注解的配置类,一般为@SpringBootApplication注解或者@Configuration注解等。SpringApplication初始化启动时,与基于JavaConfig的方式一样,也是通过AnnotatedBeanDefinitionReader来将启动类作为BeanDefinition注册到BeanFactory的,之后使用ConfigurationClassPostProcessor来处理相关注解。

@Configuration注解的类的加载(注意不是处理@Configuration注解处理)实现原理相关推荐

  1. Spring:@AutoConfigurexxx注解-控制配置类的加载顺序

    1.美图 2.概述 控制配置类的加载顺序(@AutoConfigureAfter.@AutoConfigureBefore.@AutoConfigureOrder) AutoConfigureAfte ...

  2. 注解与反射 - 反射 - 类的加载

    所有Class 的对象 哪些类型可以有Class对象? class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类. interface: 接口 []:数组 enum:枚举 annot ...

  3. WEB——BaseDao、注解、Servlet3.0、动态代理、类的加载器

    **编写BaseDao**          1.dao持久层怎么来写的?     2.编写通用的BaseDao,其他的Dao的持久层继承BaseDao,提供增删改查的方法了.          3. ...

  4. DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描...

    DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描 liuyuhang原创,未经允许禁止转载    系列目录连接 DB数据源之Spr ...

  5. Spring 使用注解@DependsOn控制Bean加载顺序

    文章目录 1. 前言 2. 代码实现 1. 前言 默认情况下,Spring加载Bean的顺序是不确定的(或者可以理解为,按编译后的class文件顺序加载).当我们需要控制Bean加载顺序以满足特定的需 ...

  6. 还在对java类、类的加载一知半解?这篇文章相信会解决你80%的困惑

    目录 什么是Class类 Class类的常用方法 获取Class类的实例 哪些类型可以有Class对象? 类加载内存分析 类加载的过程 类的加载与ClassLoader的理解 什么时候会发生类初始化? ...

  7. 第十九章《类的加载与反射》第3节:反射

    JAVA的反射机制是指在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性.这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的 ...

  8. 尚硅谷 宋红康 JVM教程_02_字节码与类的加载篇

    本系列相关链接 尚硅谷 宋红康 JVM教程_01_内存与垃圾回收篇--01 (20210103-20210110) https://blog.csdn.net/wei198621/article/de ...

  9. Java中的类加载器(ClassLoader)及类的加载机制

    类加载器就是用来将class文件加载到内存中的一个java类! 系统默认有三个类加载器! ①BootStrap:这不是java类,是java虚拟机在启动的时候加载的第一个类,这个加载器用来加载核心类, ...

最新文章

  1. 文件操作03——图片文件合成器
  2. linux: convmv =-======pkgs.org
  3. snmp agent
  4. Python pygame
  5. MM 收货容差如何设定
  6. 【Linux系统编程】进程间通信概述
  7. .NET6之MiniAPI(九):基于角色的身份验证和授权
  8. ExtJS和AngularJS比较
  9. BugTracker.NET安装指南
  10. 异构计算崛起,GPU加速计算服务器FP5468G2应运而生
  11. python linkedlist,LinkedList在python中的实现
  12. NP、OSPF虚链路
  13. Vijos 1303
  14. 计算机没网络怎么更新网卡驱动,电脑显示没有网卡驱动怎么办?电脑显示没有网卡驱动的解决方法...
  15. 按压式按摩靠背的设计
  16. 在线教育项目-npm install失败-下载依赖失败-(vue-admin-template-master)
  17. 软考学习:吐血整理——自学软考的终极干货
  18. Selenium如何使用句柄方式切换窗口?
  19. 调整HTML5画布中图像的大小
  20. 多重背包问题和“二进制拆分”

热门文章

  1. Xshell 命令换行
  2. Python均匀分布和三角形分布
  3. java技术微信公众号
  4. 直播-拉流和推流概述
  5. R7000P双系统装机记录
  6. linux 安全狗 加入云服务,云服务器如何安装安全狗
  7. MCE公司:靶向 STING 蛋白的共价抑制剂有望用于治疗自身免疫性疾病
  8. 如何从 Android 手机上的 SD 卡恢复已删除的照片
  9. JAVA学习---数组
  10. 计算机科学与技术这个专业哪个大学最好,计算机科学与技术专业哪个大学好