简介
对于基于Spring
框架开发的一个应用系统,其中每一个bean
都来自于一个bean
定义:开发人员的某个bean
定义,框架自身的某个bean
定义,三方库的某个bean
定义。这些概念上的bean
定义,通过Spring
接口BeanDefinition
被建模,并且在应用运行时都会以一个BeanDefinition
对象的形式被注册到Spring IoC
容器中。所以说,bean
定义,或者说,BeanDefinition
接口,是整个Spring
容器的根本概念之一。
一个BeanDefinition
描述和定义了创建一个bean
需要的所有信息,属性,构造函数参数以及访问它们的方法。还有其他一些信息,比如这些定义来源自哪个类等等。
接口BeanDefinition
简介
Spring
框架中的接口BeanDefinition
顾名思义,就是"bean定义"的意思,它定义了创建相应的bean
使用如下属性 :
属性名称 | 介绍 |
---|---|
parentName | 双亲bean 定义(parent bean definition )的名称.如果没有双亲bean定义,这里为空 |
beanClassName | bean 的类名,在bean factory 的post process 阶段可能会被修改。注意该属性并不总是运行时被对应bean 真正使用的类的名称:比如,bean 是通过某个类的静态工厂方法生成的,这里是该类的类名,再比如,bean 是通过一个工厂bean 生成的,那这里为空。 |
scope | 作用域, singleton 或者prototype 。在bean 的作用域尚未决定之前,该属性为null |
lazyInit | 是否懒加载,仅适用于singleton bean 。当一个singleton bean 被指定lazyInit 为false 时,它会在bean factory 启动时执行singleton bean 初始化的阶段被实例化。 |
dependsOn | 所依赖的bean 的名称,如果有多个依赖的bean ,这里需要都列出来。容器会保证这些被依赖的bean 先被初始化。 |
autowireCandidate | 该bean 是否作为自动绑定的候选,仅适用于基于类型的自动绑定。基于名称的绑定不受此属性影响。 |
primary | 当前bean 定义是否主bean 。当某个自动绑定遇到多个候选bean 时,primary 属性为true 的会被使用。 |
factoryBeanName | 如果要使用factory bean 来创建bean ,这里指定了相应的工厂bean 的类名称 |
factoryMethodName | 工厂方法名称。基于类静态工厂方法的情况下,结合beanClassName 使用;基于工厂bean 的情况下,结合factoryBeanName 使用。如果bean 定义的constructorArgumentValues 有内容,工厂方法被调用时会使用该属性。 |
constructorArgumentValues | bean 创建时的构造函数参数 |
propertyValues | 新建的bean 需要设置的属性值 |
initMethodName | bean 的初始化方法 |
destroyMethodName | bean 的析构方法 |
role | bean 的角色:APPLICATION ,SUPPORT ,INFRASTRUCTURE 。提示框架该bean 的角色和重要程度。 |
description | bean 的描述,human readable |
singleton | 作用域断言,是否singleton |
prototype | 作用域断言,是否prototype |
abstract | 是否抽象bean 定义,抽象bean 定义的目的不是用于实例化bean ,而是有其他目的。 |
resourceDescription | 资源描述文本,告知当前bean 定义的来源,一般用于错误时显示上下文。 |
originatingBeanDefinition | 返回来源bean 定义(如果有的话)。通过该属性,可以获取被修饰的bean 定义。需要注意的是该属性仅仅返回直接 来源bean 定义而不是返回最深处 的来源bean 定义。一个bean 定义的originatingBeanDefinition 属性隐含了一个来源bean 定义链,通过迭代访问该链,可以最终找到最终来自用户的bean 定义。 |
上表中提到的bean
的角色,分别是:
APPLICATION
– 指出该bean
是应用程序的主要部分,通常对应用户定义的bean
。SUPPORT
– 应用支持性质的bean
,在某些地方比较重要,但从整个应用的返回来看,还没那么重要。INFRASTRUCTURE
– 基础设施bean
,仅仅用于框架内部工作,跟终端用户无关。
除了上述直接通过BeanDefinition
自身进行的定义,,接口BeanDefinition
还继承了另外两个接口 : AttributeAccessor
和BeanMetadataElement
。
AttributeAccessor
接口定义了对一个bean
属性的访问 :
方法 | 介绍 |
---|---|
setAttribute | 设置指定的属性为特定值 |
getAttribute | 获取指定的属性的值 |
removeAttribute | 删除指定的属性 |
hasAttribute | 是否拥有指定的属性 |
attributeNames | 获取所有属性的名称 |
BeanMetadataElement
接口定义了一个bean
定义的配置来源:
方法 | 介绍 |
---|---|
getSource | 获取当前元数据元素的配置来源类 |
接口BeanDefinition
实现类简介
BeanDefinition
接口有一些实现类,并且这些实现类有一些共同的基础逻辑。这些实现类主要是 : RootBeanDefinition
,ChildBeanDefinition
和GenericBeanDefinition
。它们共同的基础逻辑实现在抽象类AbstractBeanDefinition
。这些类之间的层级关系如下:
各个接口BeanDefinition
实现类使用注意事项
一般建议
一般情况下,建议使用GenericBeanDefinition
用于定义用户可见的bean
定义。而对于一些父子关系已经确定的情况,使用RootBeanDefinition
/ChildBeanDefinition
。
各个实现类的区别/特点
RootBeanDefinition
– 不能设置parent bean
定义
由此可见,
RootBeanDefinition
不能用于用于父子bean
定义关系中的"子bean
定义"
ChildBeanDefinition
– 必须设置parent bean
定义,而且必须是通过构造函数指定
ChildBeanDefinition
很适合父子bean
定义关系明确的情况下基于双亲bean
定义和自身少量设置一些个性化属性从而进行子bean
定义。
实际上,真正在创建子bean
定义规定的bean
对象时,Spring
框架内部是将双亲bean
定义和孩子bean
定义合并形成一个最终使用的RootBeanDefinition
,这里孩子bean
定义中设置的属性会被优先使用,没有指定的都会继承使用双亲bean
定义中的设置。
GenericBeanDefinition
– 可以动态设置parent bean
定义,也可以不设置parent bean
定义
由此可见,
GenericBeanDefinition
既可以替代RootBeanDefinition
,也可以替代ChildBeanDefinition
,所以GenericBeanDefinition
更一般化(generic
)
相关文章
Spring的bean定义 1 : 基础建模–接口BeanDefinition
Spring的bean定义 2 : 通用bean定义逻辑 – AbstractBeanDefinition
Spring的bean定义 3 : BeanDefinition实现类例子演示
Spring的bean定义 4 : 合并了的bean定义–MergedBeanDefinition