目录
2.5、 AnnotatedGenericBeanDefinition类
2.6、 ScannedGenericBeanDefinition类
3.3、depends-on/init-method/destory-method
3.4、factory-bean/factory-method
至此BeanDefintion家族相关类以及使用总结完毕。笔者才疏学浅,在本篇博文的分析中如果有理解不到的地方,欢迎大家批评指正。
前言:
笔者在一篇关于Spring的BeanFactory的分析的时候数次被BeanDefintion接口弄的云里雾里(有关笔者的Spring源码分析之一BeanFactory相关 感兴趣的可以看看),影响了自己对BeanFactory的阅读。这里趁这次机会好好的捋一捋有关BeanDefinition的家族系列。
一、BeanDefinition的家族系列
1、BeanDefintion的UML类图
话不多说直接上图,让我们一睹BeanDefinition的大家族。原谅笔者不才无法用一张UML类图概括完整个BeanDefinition家族
AnnotatedGenericBeanDefinition UML类图
ChildBeanDefinition UML类图
RootBeanDefinition UML类图
Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构。BeanDefintion是Spring提供的将我们使用xml或者注解修饰的需要spring管理的bean实例统一使用BeanDefintion抽象模式存放,并同时提供有关bean的其他属性信息(spring定义的),注入类型,是否懒加载 ,scope等等,从而便于spring管理和使用。
2、BeanDefintion家族类详解
2.1、通用接口
BeanDefintion实现类都会直接或者间接的继承如下接口:
- AttributeAccessor 接口提供相关属性attribute的设置和读取操作设置属性可以通过xml的<meta key="" value=""/>设置
- BeanMetadataElement接口获取一个包含元数据元素的配置源对象
- AttributeAccessorSupport抽象类 实现了AttributeAccessor接口 使用Map来提供属性的访问和操作
- BeanMetadataAttributeAccessor类 继承AttributeAccessorSupport 实现BeanMetadataElement 新增的功能是访问BeanMetadataAttribute类型的属性。
2.2、BeanDefintion接口
BeanDefintion是Beandefintion系列的顶层接口,继承AttributeAccessor接口和BeanMetadataElement接口 所以具备了访问bean属性 以及获取源对象的功能。 spring将我们需要托管的bean都转换为 BeanDefinition 该接口中包含如下属性setter getter接口方法:
parentName: 父beanDefinition 名
beanClassName: bean实例对象的class名字
scope: 单例或者原型
lazyInit: 是否懒加载
dependsOn: 该bean定义所有依赖的beanName 列表
autowireCandidate:是否为注入的候选者
autowire-candidate 属性设置为 false, 这样容器在查找自动装配对象时 将不考虑该 bean,
即它不会被考虑作为其他 bean 自动装配的候选者,
但是该 bean 本身还是可以使用自动装配来注入其他的 bean
primary:是否为唯一的注入候选者
factoryBeanName: 创建该bean的工厂BeanName
factoryMethodName:创建该bean的工厂MethodName
ConstructorArgumentValues:构造参数包装类
MutablePropertyValues:可变属性列表
scope:是否单例 是否原型
role: 用于标识Bean的分类 有三种标识1、用户定义的bean ROLE_APPLICATION 2、某些复杂的配置ROLE_SUPPORT 3、完全内部使用ROLE_INFRASTRUCTURE
description 获取描述
description:返回该bean定义来自的资源的描述(用于在出现错误时显示上下文)
originatingBeanDefinition:获取原始的bean定义
2.3、AbstractBeanDefintion抽象类
AbstractBeanDefintion抽象类完全的实现了BeanDefinition中定义的所有接口(提供了默认的实现方式),同时也提供了一些扩展字段qualifiers属性、MethodOverrides属性等。
// Bean 的Class 对象
private volatile Object beanClass;
// bean 的作用范围, 对应 bean 属性 scope (常见的就是单例/原型)
private String scope = SCOPE_DEFAULT;
// 是否是抽象, 来自 bean 属性的 abstract(抽象的类是不能直接生成对象)
private boolean abstractFlag = false;
// 是否延迟加载, 对应 bean 属性 lazy-init (值是否在使用 Bean的时候才正真的创建 Bean)
private boolean lazyInit = false;
// 自动注入模式, 对应 bean 属性 autowire (这个属性主要指 XML 描述的 beanDefinition, 在生成bean的对吼阶段, 获取容器中的对象, 自动装配在 BeanDefinition 对应的 Field 上)
private int autowireMode = AUTOWIRE_NO;
// 依赖检查, Spring 3.0 后 弃用这个属性
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
// 用来表示一个 bean 的实例化依靠另一个 bean 先实例化(PS: 这个很少使用了)
private String[] dependsOn;
/**
* autowire-candidate 属性设置为 false,
* 这样容器在查找自动装配对象时
* 将不考虑该 bean, 即它不会被考虑作为其他 bean
* 自动装配的候选者, 但是该 bean
* 本身还是可以使用自动装配来注入其他的 bean
*/
private boolean autowireCandidate = true;
// 自动装配时当出现多个 bean 候选者时, 将作为首候选者 (PS: 使用比较少)
private boolean primary = false;
// 用于记录 Qualifier, 对应子元素 qualifier(当使用 @Autowired 时, 有多个候选Bean 时, 就通过这个Qualifier 来进行区分)
private final Map<String, AutowireCandidateQualifier> qualifiers =
new LinkedHashMap<String, AutowireCandidateQualifier>(0);
// 允许访问非公开的构造器和方法, 程序设置 (PS: 用得比较少)
private boolean nonPublicAccessAllowed = true;
/**
* 是否以一种宽松的模式解析构造函数, 默认 true
* 如果是 false, 则在如下情况
* interface ITest()
* class ITestImpl implement ITest();
* class Main {
* Main(ITest i) {}
* Main(ITestImpl i) {}
* }
* 抛出异常, 因为 Spring 无法准确确定哪个构造函数
* 程序设置
*
* lenient 宽大, 仁慈
*/
private boolean lenientConstructorResolution = true;
/**
* 对应 bean 属性 factory-bean 用法 (PS: 这里涉及 FactoryBean 这个概念, 这个类主要是解决: 创建一个类, 但创建这个类的过程比较长/条件比较多, 这时候就使用同一的抽象工厂模式(FactoryBean对象) 来创建对象)
* <bean id="instanceFactoryBean" class="example.chapter3.InstanceFactoryBean />
* <bean id="currentTime" factory-bean="instanceFactoryBean" factory-method="createTime" />
*/
private String factoryBeanName;
// 对应 bean 属性 factory-method
private String factoryMethodName;
// 记录构造函数注入属性, 对应 bean 属性 constructor-arg
private ConstructorArgumentValues constructorArgumentValues;
// 普通属性集合 (在XML 中定义Bean的信息时, 通常propertyValues里面有很多依赖信息)
private MutablePropertyValues propertyValues;
// 方法重写的持有者, 记录 lookup-method, replaced-method 元