@Configuration注解的类的加载(注意不是处理@Configuration注解处理)实现原理
概述
- 这里主要分析@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方法的执行,会注册三个注解处理器,分别是:
- ConfigurationClassPostProcessor:BeanFactoryPostProcessor接口的实现类,处理@Configuration,@Component,@ComponentScan,@Import,@ImportResource或@Bean注解。
- AutowiredAnnotationBeanPostProcessor:BeanPostProcessor接口实现类,处理@Autowired注解。
- CommonAnnotationBeanPostProcessor:BeanPostProcessor接口实现类,处理JDK提供的注解,如@PostConstruct,@PreDestroy,@Resource等。
- 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处理其上的注解。
- 基于applicationContext.xml:使用<context:component-scan />标签,并在base-package属性指定的@Configuration类所在的包,则Spring容器启动时,就会加载@Configuration注解类并创建BeanDefinition对象注册到BeanFactory中,之后ConfigurationClassPostProcessor作为BeanFactoryPostProcessor,从BeanFactory取出并赛选使用了@Configuration注解的类对应的的BeanDefinition,处理其上的@ComponentScan等注解和类内部使用@Bean注解的方法。
- 基于JavaConfig的方式,在WebApplicationInitializer接口实现类的onStartup方法中,以@Configuration注解的类作为构造函数参数,创建AnnotationConfigApplicationContext对象,然后交给该对象以attribute方式添加到ServletContext中。此时AnnotationConfigApplicationContext在内部会使用AnnotatedBeanDefinitionReader注册这个使用了@Configuration注解的配置类到BeanFactory中。之后ConfigurationClassPostProcessor完成与基于applicationContext.xml的方式中一样的处理。
- SpringBoot的处理方式:SpringBoot的SpringApplication使用AnnotationConfigApplicationContext作为Spring容器的ApplicationContext,然后将main方法所在启动类作为参数调用SpringApplication.run方法,其中该启动类为一个基于注解的配置类,一般为@SpringBootApplication注解或者@Configuration注解等。SpringApplication初始化启动时,与基于JavaConfig的方式一样,也是通过AnnotatedBeanDefinitionReader来将启动类作为BeanDefinition注册到BeanFactory的,之后使用ConfigurationClassPostProcessor来处理相关注解。
@Configuration注解的类的加载(注意不是处理@Configuration注解处理)实现原理相关推荐
- Spring:@AutoConfigurexxx注解-控制配置类的加载顺序
1.美图 2.概述 控制配置类的加载顺序(@AutoConfigureAfter.@AutoConfigureBefore.@AutoConfigureOrder) AutoConfigureAfte ...
- 注解与反射 - 反射 - 类的加载
所有Class 的对象 哪些类型可以有Class对象? class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类. interface: 接口 []:数组 enum:枚举 annot ...
- WEB——BaseDao、注解、Servlet3.0、动态代理、类的加载器
**编写BaseDao** 1.dao持久层怎么来写的? 2.编写通用的BaseDao,其他的Dao的持久层继承BaseDao,提供增删改查的方法了. 3. ...
- DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描...
DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描 liuyuhang原创,未经允许禁止转载 系列目录连接 DB数据源之Spr ...
- Spring 使用注解@DependsOn控制Bean加载顺序
文章目录 1. 前言 2. 代码实现 1. 前言 默认情况下,Spring加载Bean的顺序是不确定的(或者可以理解为,按编译后的class文件顺序加载).当我们需要控制Bean加载顺序以满足特定的需 ...
- 还在对java类、类的加载一知半解?这篇文章相信会解决你80%的困惑
目录 什么是Class类 Class类的常用方法 获取Class类的实例 哪些类型可以有Class对象? 类加载内存分析 类加载的过程 类的加载与ClassLoader的理解 什么时候会发生类初始化? ...
- 第十九章《类的加载与反射》第3节:反射
JAVA的反射机制是指在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性.这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的 ...
- 尚硅谷 宋红康 JVM教程_02_字节码与类的加载篇
本系列相关链接 尚硅谷 宋红康 JVM教程_01_内存与垃圾回收篇--01 (20210103-20210110) https://blog.csdn.net/wei198621/article/de ...
- Java中的类加载器(ClassLoader)及类的加载机制
类加载器就是用来将class文件加载到内存中的一个java类! 系统默认有三个类加载器! ①BootStrap:这不是java类,是java虚拟机在启动的时候加载的第一个类,这个加载器用来加载核心类, ...
最新文章
- 文件操作03——图片文件合成器
- linux: convmv =-======pkgs.org
- snmp agent
- Python pygame
- MM 收货容差如何设定
- 【Linux系统编程】进程间通信概述
- .NET6之MiniAPI(九):基于角色的身份验证和授权
- ExtJS和AngularJS比较
- BugTracker.NET安装指南
- 异构计算崛起,GPU加速计算服务器FP5468G2应运而生
- python linkedlist,LinkedList在python中的实现
- NP、OSPF虚链路
- Vijos 1303
- 计算机没网络怎么更新网卡驱动,电脑显示没有网卡驱动怎么办?电脑显示没有网卡驱动的解决方法...
- 按压式按摩靠背的设计
- 在线教育项目-npm install失败-下载依赖失败-(vue-admin-template-master)
- 软考学习:吐血整理——自学软考的终极干货
- Selenium如何使用句柄方式切换窗口?
- 调整HTML5画布中图像的大小
- 多重背包问题和“二进制拆分”