概述
我们知道Spring中Bean的配置来源很多(主要两种方式定义一个 Bean:面向资源(XML、Properties)、面向注解),为了收集不同配置源,需要统一起来,所有有必要使用一个对象存储 也就是BeanDefinition,而在使用这些BeanDefinition之前,不同的BeanDefinition直接也会存在不同的依赖层级和引用关系。遵循单一职责、开闭原则 还需要划分增强这些BeanDefinition,最后再统一成功能增强的BeanDefinition,就是合并后的RootBeanDefinition 。
最后将我们的配置信息转换成 Spring Bean,并管理着这些Bean的生命周期
Spring Bean 的生命周期 可以看到,BeanDefinition 可以说是 Bean 的“前身”,首先进入 Bean 的元信息的配置、解析和注册阶段,然后才开始 Bean 的实例化和初始化等工作。
BeanDefinition 是 Spring Framework 中定义 Bean 的配置元信息接口,主要包含一下信息:
Bean 的类名
Bean 行为配置类,如作用域、自动绑定模式(自动装配模式)、生命周期回调等
其他 Bean 引用,又可称作合作者或者依赖
配置设置,比如 Bean 属性
Bean 的“前身”
Spring中不同BeanDefinition的关系图
分析
BeanDefinition 继承体系结构
AttributeAccessor接口:用于获取元数据,在实现类中通过 LinkedHashMap 集合保存元数据,例如通过 XML 的 <meta /> 标签定义的一些元信息会保存在其中
BeanMetadataElement接口:用于获取定义 Bean 的源对象,在实现类中通过 Object 对象保存,所谓的源对象就是定义这个 Bean 的资源(XML 标签对象或者 .class 文件资源对象)
BeanDefinition接口:定义一个 Bean 的元信息
AbstractBeanDefinition抽象类:实现 BeanDefinition 接口,包含了一个 Bean 几乎所有的元信息:
GenericBeanDefinition:继承 AbstractBeanDefinition 抽象类,多了一个 parentName,表示有继承关系,是一个标准 Bean 元信息对象,通过 XML 定义的 Bean 会解析成该对象
AnnotatedBeanDefinition接口:继承 BeanDefinition 接口,定义注解类的元信息,例如通过 @Component 注解定义的 Bean,那么注解类的元信息中会包含编译后的 .class 文件的所有信息
ScannedGenericBeanDefinition:,继承 GenericBeanDefinition,实现 AnnotatedBeanDefinition 接口,多了一个 AnnotationMetadata 注解类元信息对象,例如通过 @Component 注解定义的 Bean 会解析成该对象
AnnotatedGenericBeanDefinition:继承 GenericBeanDefinition,实现 AnnotatedBeanDefinition 接口,和 ScannedGenericBeanDefinition 类似,通过 @Import 导入的 Configuration Class 会解析成该对象
RootBeanDefinition:继承 AbstractBeanDefinition 抽象类,表示合并后的 BeanDefinition 对象。在 Spring BeanFactory 初始化 Bean 的前阶段,会根据 BeanDefinition 生成一个 RootBeanDefinition(具有层次性则会进行合并),用于后续实例化、属性注入和初始化
ConfigurationClassBeanDefinition:私有静态类,继承 RootBeanDefinition,实现了 AnnotatedBeanDefinition 接口,和 AnnotatedGenericBeanDefinition 类似,没有继承关系(就是没有继承GenericBeanDefinition),通过 @Bean 定义的方法会解析成该对象
BeanDefinitionHolder: 包含 BeanDefinition、Bean 的名称以及别名(支持多个)
BeanDefinition 接口的实现类主要根据 Bean 的定义方式进行区分,如下:
XML 定义 Bean >>>>> GenericBeanDefinition
@Component 以及派生注解定义 Bean >>>>> ScannedGenericBeanDefinition
借助于 @Import 导入 Bean >>>>> AnnotatedGenericBeanDefinition
@Bean 定义的方法 >>>>> ConfigurationClassBeanDefinition
在 Spring BeanFactory 初始化 Bean 的前阶段,会根据 BeanDefinition 生成一个合并后的 RootBeanDefinition 对象
在解析出来 BeanDefinition 后都会转换成 BeanDefinitionHolder 对象,然后进行注册,,知道为啥不直接使用BeanDefinition? 留个悬念啊下一篇会分析的
总结
Spring Bean 的“前身”为 BeanDefinition 对象,里面包含了 Bean 的元信息,后续在 Bean 的生命周期中会根据BeanDefinition对象进行实例化、属性注入和初始化等工作
BeanDefinition 接口的实现类主要根据 Bean 的定义方式进行区分,如下:
XML 定义 Bean:GenericBeanDefinition
@Component 以及派生注解定义 Bean:ScannedGenericBeanDefinition
借助于 @Import 导入 Bean:AnnotatedGenericBeanDefinition
@Bean 定义的方法:ConfigurationClassBeanDefinition 私有静态类(ConfigurationClassBeanDefinitionReader的内部类)
上面的 1、2、3 三种 BeanDefinition 实现类具有层次性(就是继承实现关系,来自于GenericBeanDefinition具有的功能),在 Spring BeanFactory 初始化 Bean 的前阶段,会根据 BeanDefinition 生成一个合并后的 RootBeanDefinition 对象