Spring源码-BeanDefinition

我们在xml中配置的bean标签、我们平时用的Component等注解标注的类,在容器中都会转化成BeanDefinition缓存在BeanDefinitionRegistry中。

在上一章Spring源码-类扫描器-ClassPathBeanDefinitionScanner中介绍了通过scan(basePackages)来从指定basePakcages下的class文件到ScannedGenericBeanDefinition的过程,我们本章就以ScannedGenericBeanDefinition来描述BeanDefinition。

类图:

avator

ScannedGenericBeanDefinition继承自GenericBeanDefinition,GenericBeanDefinition继承自AbstractBeanDefinition,AbstractBeanDefinition实现了BeanDefinition接口。

同时实现了AnnotatedBeanDefinition接口用于访问注解的信息。

BeanDefinition

方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
String: getBeanClassName: 返回当前bean definition定义的类名
ConstructorArgumentValues: getConstructorArgumentValues:返回bean的构造函数参数
String[]: getDependsOn:返回当前bean所依赖的其他bean的名称
String: getFactoryBeanName: 返回factory bean的名称
String: getFactoryMethodName: 返回工厂方法的名称
BeanDefinition: getOriginatingBeanDefinition: 返回原始的BeanDefinition,如果不存在返回null
String: getParentName: 返回当前bean definition的父definition的名字
MutablePropertyValues: getPropertyValues: 返回一个用于新的bean实例上的属性值
String: getScope: 返回当前bean的目标范围
boolean: isAbstract: 当前bean是否是abstract,意味着不能被实例化
boolean: isLazyInit: bean是否是延迟初始化
boolean: isPrimary: bean是否为自动装配的主要候选bean
boolean: isPrototype: bean是否是多实例
boolean: isSingleton: bean是否是单例
void: setAutowiredCandidate(boolean): 设置bean是否对其他bean是自动装配的候选bean
void: setBeanClassName(String): 指定bean definition的类名
void: setDependsOn(String ...): 设置当前bean初始化所依赖的beans的名称
void: setFactoryBeanName(String): 如果factory bean的名称
void: setFactoryMethodName(String): 设置工厂的方法名
void: setLazyInit(boolean lazyInit): 设置是否延迟初始化
void: setParentName(String): 设置父definition的名称
void: setPrimary(boolean): 设置是否主要的候选bean
void: setScope(String): 设置bean的范围,如:单例,多实例

AnnotatedBeanDefinition

功能
继承了BeanDefinition接口,并添加了对注解元数据访问的方法

方法

1
2
AnnotationMetadata getMetadata(): 获得当前bean definition 的bean 类(class)的注解元数据
MethodMetadata getFactoryMethodMetadata(): 获得当前bean definition 的工厂方法上的元数据

AbstractBeanDefinition、GenericBeanDefinition

功能
BeanDefinition的实现抽象类,GenericBeanDefinition继承自AbstractBeanDefinition

RootBeanDefinition

功能
spring的BeanDefinition有可能会包含parentName属性对应parentBeanDefinition,RootBeanDefinition会和parent的BeanDefinition进行Merge,容器根据RootBeanDefinition实例化对象。

应用

  • 在refresh方法的preInstantiateSingletons()中,将所有的non-lazy-init的单例的BeanDefinition实例化,
  • getType、getBean

    关键代码:getMergedBeanDefinition 将parentBeanDefinition和childBeanDefinition合并。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {

synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;

// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}

if (mbd == null || mbd.stale) {
previous = mbd;
//没有parentBean,直接clone或者create
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
// Child bean definition: needs to be merged with parent.
//获取parentBean
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
//beanName和parentBeanName不相等,后去parentBean
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
//如果相等,parentFactory是ConfigurableBeanFactory,merge(这里本质上是递归的方式,知道所有的parent都merge)
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);//创建parent的Root
mbd.overrideFrom(bd);//merage
}

// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}

// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}

// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}