Spring IoC 源码解析:创建和初始化 bean 实例

到目前为止,我们已经分析了 bean 配置的解析与注册过程。经过这一系列的操作,我们编写在 XML 中的半结构化静态配置已经转换成一个个的 BeanDefinition 实例存在于容器之中,接下来就可以调用 BeanFactory#getBean 方法获取目标 bean 实例。本文我们将从 BeanFactory#getBean 方法出发,探究容器基于 BeanDefinition 创建和初始化 bean 实例的过程。

下图描绘了从 BeanFactory 中按照 beanName 获取 bean 实例的核心过程:

image

我们可以从整体上将 bean 的生命周期分为 5 个阶段:

  1. 实例化 bean 对象;
  2. 执行属性注入;
  3. 执行初始化(调用 InitializingBean#afterPropertiesSet 方法和 init-method 方法);
  4. 使用 bean 实例;
  5. 销毁 bean 实例(调用 DisposableBean#destroy 方法和 destroy-method 方法)。

Spring 会在 bean 实例的生命周期中设置多个拦截器,主要可以分为以下几类(按照生命周期进行排序):

  1. 实例化前置拦截器:我们可以在该拦截器中自定义实例化,从而替换 Spring 自身的实例化操作。
  2. Bean Definition 拦截器:用于在实例化 bean 对象之前对 bean 定义进行拦截修改。
  3. 实例化后置拦截器:此时还未执行属性注入,所以我们可以在此实现自定义属性注入逻辑。
  4. 属性拦截器:用于在执行属性注入之前对待注入的属性值进行修改。
  5. Aware 拦截器:实现了这类拦截器的 bean 希望在 IoC 容器初始化期间从容器中获取一些属性。
  6. 初始化前置拦截器:在执行初始化方法之前对 bean 实例进行拦截处理。
  7. 初始化后置拦截器:在执行初始化方法之后对 bean 实例进行拦截处理。
  8. 销毁前置拦截器:在销毁 bean 实例之前对 bean 实例进行拦截处理。

以上我们从 bean 实例整体生命周期的角度对 IoC 容器从创建到最终销毁一个 bean 实例的过程进行了简单的概括,下面我们将从源码实现的层面去分析 IoC 容器是如何创建并初始化 bean 实例的。

我们从 BeanFactory#getBean 方法切入,Spring 为该方法提供了多种重载和覆盖版本的实现,当我们执行该方法时一般都是由抽象类 AbstractBeanFactory 予以处理。

方法 AbstractBeanFactory#getBean 实现如下:

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, null, null, false);
}

protected <T> T doGetBean(final String name,
@Nullable final Class<T> requiredType,
@Nullable final Object[] args,
boolean typeCheckOnly) throws BeansException {

/*
* 获取 name 对应的真正 beanName
*
* 因为传入的参数可以是 alias,也可能是 FactoryBean 的 name,所以需要进行解析,包含以下内容:
* 1. 如果是 FactoryBean,则去掉 “&” 前缀
* 2. 沿着引用链获取 alias 对应的最终 name
*/
final String beanName = this.transformedBeanName(name);
Object bean;

/*
* 尝试从单例集合中获取对应的单实例,
* 在实例化 bean 的时候可能需要实例化依赖的 bean 对象,Spring 为了避免循环依赖会采用早期引用机制
*/
Object sharedInstance = this.getSingleton(beanName);
// 目标实例已经实例化过
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 处理 FactoryBean
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 目标实例不存在
else {
// Fail if we're already creating this bean instance: We're assumably within a circular reference.
if (this.isPrototypeCurrentlyInCreation(beanName)) {
/*
* 只有在单例模式下才会尝试解决循环依赖问题,
* 对于原型模式,如果存在循环依赖,直接抛出异常
*/
throw new BeanCurrentlyInCreationException(beanName);
}

// 获取父 BeanFactory 实例
BeanFactory parentBeanFactory = this.getParentBeanFactory();
// 如果已经加载的 bean 定义中不包含目标 bean,则尝试从父 BeanFactory 中获取
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
// 递归到父 BeanFactory 中进行检索
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory)
.doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
} else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}

// 如果不仅仅是做类型检查,则标记该 bean 即将被创建
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}

try {
// 如果存在父 bean,则继承父 bean 定义
final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
// 检查 bean 是否是抽象的,如果是则抛出异常
this.checkMergedBeanDefinition(mbd, beanName, args);

// 加载当前 bean 依赖的 bean 实例
String[] dependsOn = mbd.getDependsOn();
// 存在依赖,递归实例化依赖的 bean 实例
if (dependsOn != null) {
for (String dep : dependsOn) {
// 检查是否存在循环依赖
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 缓存依赖调用
this.registerDependentBean(dep, beanName);
try {
// 初始化依赖的 bean 实例
this.getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

/* 创建 bean 实例 */

// scope == singleton
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
// 实例化 bean 对象
return this.createBean(beanName, mbd, args);
} catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
this.destroySingleton(beanName); // 清理工作,从单例缓存中移除
throw ex;
}
});
// 处理 FactoryBean
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// scope == prototype
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 设置正在创建的状态
this.beforePrototypeCreation(beanName);
// 创建 bean 实例
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
// 处理 FactoryBean
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// other scope
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);
try {
return this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
});
// 处理 FactoryBean
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex);
}
}
} catch (BeansException ex) {
this.cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}

// 如果要求做类型检查,则检查 bean 的实际类型是否是期望的类型,对应 getBean 时指定的 requireType
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 执行类型转换,转换成期望的类型
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
} catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}

整个方法的执行流程可以概括为:

  1. 将参数 name 转换成对应的真实 beanName,因为入参可能是 alias,或者是 FactoryBean 的 name;
  2. 尝试从单例集合中获取 bean 实例,如果存在则直接返回,否则如果存在循环依赖,则尝试基于提前引用机制予以解决;
  3. 如果是获取 prototype 类型对象,则检查依赖关系,防止出现循环依赖;
  4. 如果目标 bean 不在当前 BeanFactory 的管辖范围,则尝试从父 BeanFactory 中获取;
  5. 如何当前 bean 存在继承关系,则合并父 bean 定义;
  6. 如果依赖的 bean 未被实例化,则递归实例化依赖的 bean 对象;
  7. 依据 bean 的作用域类型实例化目标 bean 对象;
  8. 如果对 bean 类型有要求,则执行类型检查,并按需做类型转换;
  9. 返回目标 bean 实例,期间会处理 FactoryBean。

接下来我们针对各步骤中的详细过程按照需要进行逐一探究。

解析 bean 标识

我们在调用 BeanFactory#getBean 方法时传递的 name 可以是 bean 的别名,也可以是获取 FactoryBean 实例的 name。所以当我们以 name 为 key 检索 bean 实例的时候,首先需要获取 name 对应的唯一标识 bean 的真正名称 beanName,这一过程位于 AbstractBeanFactory#transformedBeanName 方法中:

1
2
3
protected String transformedBeanName(String name) {
return this.canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

上述实现首先会通过 BeanFactoryUtils#transformedBeanName 工具类方法判断是不是获取 FactoryBean 实例,如果是则去掉 name 前面的 & 字符(我们已经在前面的文章中专门介绍了 FactoryBean,不熟悉的读者可以重新回顾一下),然后执行 SimpleAliasRegistry#canonicalName 逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
// 如果是别名,则直接从映射集合中获取对应的 beanName
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
// 遍历寻找真正的 name,可能存在引用链
} while (resolvedName != null);
return canonicalName;
}

前面我们在分析默认标签的解析过程时了解到,Spring 会通过调用 SimpleAliasRegistry#registerAlias 方法建立 alias 与 beanName 之间的映射关系,而这一映射关系实际上就是记录在 SimpleAliasRegistry#aliasMap 属性中,所以上述实现实际上就是从该属性中基于 alias 检索 beanName 的过程。

那么,为什么这里当 resolvedName != null 的时候需要继续循环呢?这是因为一个别名所引用的不一定是最终的 beanName,可以是另外一个别名,这个时候就是一个链式引用的场景,我们需要继续沿着引用链往下寻找最终的 beanName。

检索单实例集合

获取到 beanName 标识之后,容器首先尝试从单例对象集合中获取 bean 实例。我们知道单例对象在容器中只会存在一份,所以首先检查单例集合也符合常理,获取单例对象的方法如下:

1
2
3
4
public Object getSingleton(String beanName) {
// 允许提前引用
return this.getSingleton(beanName, true);
}

上述方法的第二个参数设置为 true,即 allowEarlyReference=true,表示允许提前引用,此时的 bean 实例虽然已经被创建,但是还未执行初始化。

Spring 中 bean 的依赖关系由开发者控制,具备极大的自由配置空间,如果配置不当可能会导致循环依赖的问题,即 A 依赖于 B,而 B 又依赖于 A。当创建 A 对象的时候,容器检测到引用的 B 还没有实例化,就会转去创建 B 对象;实例化 B 的过程中又会发现 A 还没有实例化完成,从而又回来实例化 A,因此陷入死循环。

Spring 能够解决一些场景下的循环依赖问题,而参数 allowEarlyReference 则在其中起到了关键的作用。方法 DefaultSingletonBeanRegistry#getSingleton(String, boolean) 的具体实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 尝试获取对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 实例不存在 && 正在创建中
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 尝试获取早期的实例,此时的实例还未完成初始化
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果早期的实例不存在,且允许提前引用,则基于对应的 ObjectFactory 创建
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// earlySingletonObjects 和 singletonFactories 是互斥的
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
// 返回目标单例对象,可能为 null
return singletonObject;
}

上述方法首先尝试从存放单实例的集合 DefaultSingletonBeanRegistry#singletonObjects 中获取实例,这里分为 3 种情况:

  1. 目标 bean 实例已经存在,说明之前已经实例化过,直接返回即可。
  2. 目标 bean 实例不存在,且未处于正在创建中的状态,直接返回 null,接下去会执行实例化进程。
  3. 目标 bean 实例不存在,但处于正在创建中的状态,说明存在循环依赖的情况。

针对第 3 种情况,Spring 定义了 DefaultSingletonBeanRegistry#earlySingletonObjects 属性,记录那些那些被创建出来还未执行初始化的对象。毕竟,依赖注入的过程是将一个对象的引用赋值给另一个对象的某个属性,并不要求被注入的对象已经完成了初始化。简单而言,就是先把对象间的依赖关系建立好,再去初始化各个对象,这一机制能够在一些场景下破解循环依赖的环路。

以上述 A 和 B 循环引用为例,我们可以先把 A 和 B 的对象先创建完成,期间相互引用的属性先置为 null,这样就不会阻碍这两个对象的创建过程,然后再初始化相互引用的属性值。

由上述实现还可以看到 singletonObjects 和 earlySingletonObjects 这两个属性中记录的实例是互斥的,即一个实例只可能存在于两者中的一个,不可能同时存在,这也是很容易理解的。

处理 FactoryBean

如果上一步我们获取到了单例 bean 实例,那么需要接着调用 AbstractBeanFactory#getObjectForBeanInstance 方法处理 FactoryBean。该方法在 AbstractBeanFactory#doGetBean 实现中多次被调用,每次我们获取到 bean 实例之后,不管是从单例集合中获取还是实时创建的各作用域对象,都需执行一次该方法对获取到的实例进行最后的处理。该方法的主要目的是判断当前 bean 实例是否是 FactoryBean,如果是 FactoryBean 实例,且用户又希望获取由该 FactoryBean 所创建的最终 bean 实例,此时就需要调用 FactoryBean#getObject 方法创建最终 bean 实例。

方法 AbstractBeanFactory#getObjectForBeanInstance 的实现如下:

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
protected Object getObjectForBeanInstance(Object beanInstance, // bean 实例
String name, // 请求的 beanName
String beanName, // 解析后的 beanName
@Nullable RootBeanDefinition mbd) { // 父 bean 定义

// 用户期望获取 FactoryBean 实例
if (BeanFactoryUtils.isFactoryDereference(name)) {
// NullBean 是对 null 实例的内部表示
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 获取FactoryBean,但是对应的bean并不是FactoryBean类型
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
// 标识是 FactoryBean 实例
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}

/*
* 一个 bean 实例,可以是普通的 bean,也可能是 FactoryBean 实例
* 该bean实例不是FactoryBean or 本来就是希望获取FactoryBean实例
*/
// 用户并不期望获取 FactoryBean 实例,且当前 bean 也不是 FactoryBean,直接返回
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}

/* 当前 bean 是 FactoryBean,但用户期望获取由该 FactoryBean 创建的 bean 实例 */

Object object = null;
if (mbd != null) {
// 标识是 FactoryBean 实例
mbd.isFactoryBean = true;
} else {
// 尝试从缓存中获取最终 bean 实例
object = this.getCachedObjectForFactoryBean(beanName);
}

// 基于 FactoryBean 获取最终 bean 实例
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && this.containsBeanDefinition(beanName)) {
// 执行对 bean 定义的 merge 操作
mbd = this.getMergedLocalBeanDefinition(beanName);
}
// 是否是用户定义的,而不是应用程序自己定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 核心实现,基于 FactoryBean 获取最终 bean 实例
object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}

上述方法的实现可以分为四种情况:

  1. 用户期望获取 FactoryBean 实例,当前 bean 实例是 FactoryBean 类型,直接返回。
  2. 用户期望获取 FactoryBean 实例,当前 bean 实例不是 FactoryBean 类型,抛出异常。
  3. 用户期望获取最终 bean 实例,当前 bean 实例不是 FactoryBean 类型,直接返回。
  4. 用户期望获取最终 bean 实例,当前 bean 实例是 FactoryBean 类型,需要基于 FactoryBean 创建最终 bean 实例。

前面三种情况都比较简单,重点看一下第四种情况,这一步的核心在于如何由 FactoryBean 获取到最终的 bean 实例。容器首先会尝试从缓存中获取,因为对于一些单例的 bean 来说,可能之前已经完成了实例化。Spring 定义了 FactoryBeanRegistrySupport#factoryBeanObjectCache 属性,用于记录 FactoryBean 与对应 bean 实例之间的映射关系。如果缓存不命中则执行创建过程,继续执行 FactoryBeanRegistrySupport#getObjectFromFactoryBean 方法:

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
protected Object getObjectFromFactoryBean(
FactoryBean<?> factory, // FactoryBean 实例
String beanName, // 真实 beanName
boolean shouldPostProcess) // 是否执行后处理
{
// 如果是单例,且已经实例化
if (factory.isSingleton() && this.containsSingleton(beanName)) {
synchronized (this.getSingletonMutex()) {
// 尝试从缓存中获取,key 为 factoryBeanName,value 为由 FactoryBean 创建的 bean 实例
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 调用 FactoryBean 的 getObject 方法创建对象
object = this.doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
} else {
if (shouldPostProcess) {
// 提前引用
if (this.isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
this.beforeSingletonCreation(beanName);
try {
// 后置处理
object = this.postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex);
} finally {
this.afterSingletonCreation(beanName);
}
}
// 如果最终的 bean 实例已经实例化完成,则缓存
if (this.containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
// 返回由 FactoryBean 创建的 bean 实例
return object;
}
}
// 不是单例,或未实例化过
else {
// 调用 FactoryBean 的 getObject 方法创建对象
Object object = this.doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
// 后置处理
object = this.postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}

上述实现对于单例来说保证单例在容器中的唯一性。我们期望的调用 FactoryBean#getObject 方法创建 bean 实例的逻辑位于 FactoryBeanRegistrySupport#doGetObjectFromFactoryBean 方法中。前面的文章已经介绍过 FactoryBean,并演示了 FactoryBean 的使用方法,再来回顾一下 FactoryBean 接口的定义:

1
2
3
4
5
6
7
8
9
10
public interface FactoryBean<T> {
/** 获取由 FactoryBean 创建的目标 bean 实例 */
T getObject() throws Exception;
/** 返回目标 bean 类型 */
Class<?> getObjectType();
/** 是否是单实例 */
default boolean isSingleton() {
return true;
}
}

FactoryBean 接口声明了三个方法,而 FactoryBean#getObject 方法是用来真正创建对象的地方。当我们在调用 BeanFactory#getBean 方法时如果不加 & 前缀,这个时候该方法可以看作是 FactoryBean#getObject 方法的代理方法,而具体实现就在 FactoryBeanRegistrySupport#doGetObjectFromFactoryBean 方法中:

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
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {

// 调用 getObject 方法创建最终 bean 实例,该方法由用户实现
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = this.getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
object = factory.getObject();
}
} catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}

// Do not accept a null value for a FactoryBean that's not fully initialized yet: Many FactoryBeans just return null then.
if (object == null) {
// FactoryBean 正在实例化中,此时获取最终 bean 实例太早
if (this.isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName,
"FactoryBean which is currently in creation returned null from getObject");
}
// 如果用户指定返回 null 值,则使用 NullBean 代替
object = new NullBean();
}
return object;
}

上述方法中执行 FactoryBean#getObject 的实现是我们一层层剥离外表所触及到的核心,该方法的具体实现则交给了开发者。

实例化 bean 对象

如果单例集合中不存在目标 bean 实例,那么说明当前 bean 可能是一个非单例对象,或者是一个单例但却是第一次加载。如果将前面的操作看作是获取对象,那么这里就需要真正创建对象了。在开始实例化 bean 之前,需要做如下几件事情:

  1. 对 prototype 对象的循环依赖进行检查,如果存在则直接抛出异常,而不尝试去解决循环依赖。
  2. 检测目标 bean 定义是否属于当前 BeanFactory 的管辖范围,如果不属于且同时存在父 BeanFactory,则委托给父 BeanFactory 进行处理。
  3. 检测是不是仅仅做类型检查(eg. BeanFactory#isTypeMatch),如果不是则标记该 bean 即将被创建。
  4. 如果存在父 bean,则继承父 bean 定义,并检查 bean 是否是抽象类,如果是则抛出异常。
  5. 检查依赖的 bean,如果存在且未实例化,则先递归实例化依赖的 bean 对象。

完成了上述准备工作之后,容器依据作用域采取适当的方法创建对应的 bean 实例。由于创建 prototype 类型对象,或其它作用域类型对象与创建 singleton 类型对象大同小异,所以下面以创建 singleton 类型对象为例,分析 bean 对象的实例化过程。

前面分析了从单例缓存集合中获取单例对象的实现,而能够执行到当前位置说明之前的缓存不命中,对应的单例对象还没有创建,需要实例化该对象。该过程位于 DefaultSingletonBeanRegistry#getSingleton 方法中,这是一个重载方法,与前面从缓存中获取单例对象的方法在参数上存在差别,方法实现如下:

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
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) { // singletonObjects 用于记录 beanName 与已创建的单例对象之间的映射关系
// 尝试从缓存中获取已经实例化完成的 bean 实例
Object singletonObject = this.singletonObjects.get(beanName);
// 缓存不命中,需要进行实例化
if (singletonObject == null) {
// 目标 bean 正在被销毁,期间不允许创建
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}

// 校验 bean 是否正在被实例化
this.beforeSingletonCreation(beanName);

boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}

try {
// 基于 ObjectFactory 创建 bean 对象
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
// 异常,再次尝试从缓存中获取
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
} catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 后置处理,移除正在被实例化的状态
this.afterSingletonCreation(beanName);
}

// 新创建的单例,记录到缓存中,并移除中间状态
if (newSingleton) {
this.addSingleton(beanName, singletonObject);
}
}

// 返回实例
return singletonObject;
}
}

上述方法的执行逻辑还是很直观的,概括如下:

  1. 检测 bean 是否正在被销毁,如果是则期间不允许重新实例化;
  2. 设置 bean 的状态为正在被创建;
  3. 实例化 bean 对象;
  4. 移除 bean 的正在被创建状态;
  5. 将新创建的 bean 实例记录到缓存,并返回该实例。

步骤 3 中的实例化 bean 是整个流程的关键所在,这里调用了 ObjectFactory#getObject 方法,由传入的参数我们可以知道该方法的实现如下:

1
2
3
4
5
6
7
8
9
10
11
this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
this.destroySingleton(beanName); // 清理工作,从单例缓存中移除
throw ex;
}
});

所以实例化 bean 的真正逻辑位于 AbstractAutowireCapableBeanFactory#createBean 方法中,实现如下:

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
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;

// 1.根据设置的 class 属性或 className 解析得到对应的 Class 引用
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}

// 2.校验 lookup-method 和 replaced-method 标签应用的方法是否存在
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(
mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex);
}

// 3. 应用 InstantiationAwareBeanPostProcessor 处理器
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = this.resolveBeforeInstantiation(beanName, mbdToUse);
// 如果在处理器中已经完成了对 bean 的实例化操作,则直接返回
if (bean != null) {
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex);
}

// 4. 创建 bean 实例
try {
Object beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}

该方法虽然名字叫 createBean,顾名思义是创建 bean 实例的地方,通过调用 AbstractAutowireCapableBeanFactory#doCreateBean 方法完成对 bean 的实例化。不过,在开始执行创建之前,该方法还做了一些前期准备工作,具体流程如代码注释,下面针对各个过程逐一分析。

解析 Class 引用

不知道你是否还记得,在分析标签解析的过程中对于 class 属性的解析,如果参数中传入了类加载器则会尝试获取对应的 Class 引用,否则直接记录类的全称类名。对于前者而言,这里的解析就是直接返回 Class 引用对象即可,而对于后者则需要解析获取对应的 Class 引用。相关实现位于 AbstractBeanFactory#resolveBeanClass 方法中,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
throws CannotLoadBeanClassException {

try {
// 如果之前直接存储的是 Class 引用,则直接返回
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}

// 否则由 className 解析得到对应的 Class 引用
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
this.doResolveBeanClass(mbd, typesToMatch), this.getAccessControlContext());
} else {
return this.doResolveBeanClass(mbd, typesToMatch);
}
}
// ... 省略异常处理
}

逻辑很清晰,如果 BeanDefinition 实例中记录已经是 Class 引用,则直接返回即可;否则需要进行解析,具体由 AbstractBeanFactory#doResolveBeanClass 方法实现,该方法会验证类全称类名,并利用类加载器解析获取对应的 Class 引用,具体实现不再展开。

校验 override 方法

Spring 中并不存在 <override-method /> 标签,这里的 override 指的是 <lookup-method/><replaced-method/> 这两个标签。之前解析这两个标签时是将标签配置以 MethodOverride 对象的形式记录在 AbstractBeanDefinition#methodOverrides 属性中,而这里的处理逻辑主要是逐一检查被覆盖的方法是否真实存在,如果不存在则说明配置不合法,需要抛出异常;如果存在唯一的方法版本则说明覆盖是明确的,标记 MethodOverride#overloaded 为 false 表明后期无需再依据参数类型和个数进行推测:

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
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exist and determine their overloaded status.
if (this.hasMethodOverrides()) {
// 获取之前解析的 <lookup-method/> 和 <replaced-method/> 标签配置,并逐一应用 prepareMethodOverride 方法
this.getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}

protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
// 获取指定类中指定方法的个数
int count = ClassUtils.getMethodCountForName(this.getBeanClass(), mo.getMethodName());
// 该类并未定义相应名称的方法
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + this.getBeanClassName() + "]");
}
// 该类仅定义了唯一一个相应名称的方法
else if (count == 1) {
/*
* 标记 MethodOverride 暂未被重载,避免参数类型检查的开销
*
* 如果一个方法存在多个重载版本,那么在调用及增强的时候还需要根据参数类型进行匹配来确认最终调用的方法版本,
* 如果方法未被重载,也就是对应这里的只有一个版本,就在设置重载标识为 false,后续可以直接定位方法
*/
mo.setOverloaded(false);
}
}

实例化前置处理

InstantiationAwareBeanPostProcessor 处理器一般在做基于 Spring 的基础组件研发时用的比较多,先来介绍一下该处理器的作用。该处理器的接口定义如下:

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
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

/** 实例化 bean 前调用,是对 bean 定义进行修改的最后机会 */
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}

/** 实例化 bean 后立即调用,位于属性注入之前 */
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}

/** 在将属性注入 bean 实例前对属性进行处理 */
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}

/** 该方法已过期,功能同 postProcessProperties */
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}

}

由代码注释还是能够清晰的知道这个处理器的功能的。接口中定义的方法紧挨着 bean 实例化的过程,如果我们希望在实例化前后对 bean 对象应用一些修改,可以通过实现该接口并注册到 BeanFactory 中。不过需要注意一点的是处理器会对所有的 bean 实例生效,需要处理好筛选的逻辑。

继续分析对于 InstantiationAwareBeanPostProcessor 处理器的执行逻辑。Spring 首先会去解析 bean 所属的真正 Class 引用,因为可能存在一些工厂 bean,而具体的 bean 类型还需要通过工厂方法去推测。相关实现位于 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation 方法中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 如果 bean 尚未实例化
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// 当前 bean 不是合成的,且注册了 InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
// 获取最终的 Class 引用,如果是工厂方法则获取工厂所创建的实例类型
Class<?> targetType = this.determineTargetType(beanName, mbd);
if (targetType != null) {
// 应用实例化前置处理
bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 应用实例初始化后置处理
bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
// 标识对于当前 bean 已经应用过该处理器,避免重复应用
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

接着就是调用注册的 InstantiationAwareBeanPostProcessor 处理器在创建 bean 实例之前对 BeanDefinition 进行前置处理,具体实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 应用实例化前置处理
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
// 遍历应用注册的 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法
for (BeanPostProcessor bp : this.getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}

如果 InstantiationAwareBeanPostProcessor 在执行前置处理期间完成了对 bean 的实例化操作,则会触发执行 InstantiationAwareBeanPostProcessor#postProcessAfterInitialization 方法(如下),该方法会在完成对 bean 实例的初始化操作之后被调用,而这里对于 bean 实例的创建和初始化均在 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 中已完成。

1
2
3
4
5
6
7
8
9
10
11
12
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
// 遍历应用注册的 InstantiationAwareBeanPostProcessor 的 postProcessAfterInitialization 方法
for (BeanPostProcessor processor : this.getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

注意这两个方法的后缀一个是 Instantiation,另一个是 Initialization,前者表示创建 bean 实例,后者表示对创建的 bean 实例执行初始化操作。

创建 bean 实例

如果在 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法中完成了实例化 bean 的过程,则直接返回相应的 bean 实例即可,否则就需要继续执行创建 bean 实例的过程,并且大部分 bean 实例都是在这一步完成创建的。实例化 bean 的逻辑还是相当复杂的,由 AbstractAutowireCapableBeanFactory#doCreateBean 方法实现,如下:

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

/* 1. 采用合适的方式创建 bean 对象 */

// 尝试获取对应的 FactoryBean 的 BeanWrapper 对象,如果存在则基于对应的 FactoryBean 创建 bean 对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}

// 如果对应的 FactoryBean 不存在,则采用适当的策略实例化 bean 对象
if (instanceWrapper == null) {
/*
* 采用一定的策略创建 bean 实例:
*
* 1. 如果设置了 instanceSupplier 回调,则基于该 Supplier 获取 bean 对象;
* 2. 否则,如果指定了工厂方法,则使用工厂方法创建 bean 对象;
* 3. 否则,调用相应的构造方法创建 bean 对象。
*/
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
// 获取 bean 实例
final Object bean = instanceWrapper.getWrappedInstance();
// 获取 bean 实例对应的 Class 对象
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

// 2. 应用 MergedBeanDefinitionPostProcessor 处理器
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 应用 postProcessMergedBeanDefinition 方法,@Autowired 注解即依赖此处理器实现
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}

// 3. 检查是否需要提前曝光 bean 实例,用于解决循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() // 单例
&& this.allowCircularReferences // 允许自动解决循环依赖
&& this.isSingletonCurrentlyInCreation(beanName)); // 当前 bean 正在创建中
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
// 为避免循环依赖,在完成 bean 实例化之前,将对应的 ObjectFactory 注册到容器中
this.addSingletonFactory(beanName,
// 获取 bean 的提前引用
() -> this.getEarlyBeanReference(beanName, mbd, bean));
}

// 4. 初始化 bean 实例
Object exposedObject = bean;
try {
// 对 bean 进行填充,注入各个属性值,如果存在依赖的 bean 则递归初始化
this.populateBean(beanName, mbd, instanceWrapper);
// 初始化 bean,调用初始化方法,比如 init-method
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}

// 5. 基于依赖关系验证是否存在循环依赖
if (earlySingletonExposure) {
// 获取 bean 实例
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
// 如果不允许注入 raw bean 实例 && 存在依赖的 bean
else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
// 获取依赖的 bean 的 beanName 集合
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
// 遍历逐个检测依赖的 bean 实例,记录未完成创建的 bean 实例
for (String dependentBean : dependentBeans) {
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
/*
* 因为 bean 在实例化完成之后,其依赖的 bean 实例一定也是完成实例化的,
* 如果 actualDependentBeans 不为空,则说明依赖的 bean 实例没有完成创建,存在循环依赖
*/
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}

// 6. 注册销毁机制
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}

return exposedObject;
}

上述方法的执行流程可以概括为:

  1. 采用合适的策略创建 bean 实例;
  2. 如果注册了 BeanDefinition 处理器,则在初始化 bean 实例之前对相应的 BeanDefinition 实例进行修改;
  3. 如果允许自动解决循环依赖,则提前曝光 bean 实例;
  4. 初始化 bean 实例,执行属性注入,调用初始化方法;
  5. 基于依赖关系验证是否存在未完成初始化的 bean 实例,如果存在则说明存在无法解决的循环依赖,抛出异常;
  6. 为实现了销毁逻辑的 bean 注册销毁机制。

下面逐步展开分析。首先来看 步骤一 ,这一步主要用于创建 bean 对象,Spring 在内部定义了 BeanWrapper 接口,用于对 bean 实例进行封装和操作。关于创建 bean 对象的过程,Spring 采取的策略如下:

  1. 如果是 FactoryBean,则基于 FactoryBean 对象获取最终 bean 实例;
  2. 否则,如果设置了 instanceSupplier 回调,则调用 Supplier#get 方法获取 bean 实例;
  3. 否则,如果指定了工厂方法,则调用工厂方法创建 bean 实例;
  4. 否则,基于参数调用确定版本的构造方法创建 bean 实例。

上述过程的后三步由 AbstractAutowireCapableBeanFactory#createBeanInstance 方法实现,如下:

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
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 解析 Class 对象
Class<?> beanClass = this.resolveBeanClass(mbd, beanName);
// 不是 public 类,或者对应的构造方法不能访问
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}

// 1. 如果设置了 instanceSupplier,则调用 Supplier#get 获取 bean 实例
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return this.obtainFromSupplier(instanceSupplier, beanName);
}

// 2. 如果指定了工厂方法,则使用工厂方法创建 bean 实例
if (mbd.getFactoryMethodName() != null) {
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
}

// 3. 解析并确定构造方法版本,调用构造方法创建 bean 实例
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 之前已经解析过构造方法版本,直接复用,避免重复解析
if (resolved) {
// 使用之前确定的构造方法版本
if (autowireNecessary) {
return this.autowireConstructor(beanName, mbd, null, null);
}
// 使用默认构造方法
else {
return this.instantiateBean(beanName, mbd);
}
}

// 依据参数决定使用哪个构造方法
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR
|| mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return this.autowireConstructor(beanName, mbd, ctors, args);
}

// 解析构造方法失败,使用首选的构造方法,如果有指定的话
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return this.autowireConstructor(beanName, mbd, ctors, null);
}

// 使用默认的构造方法
return this.instantiateBean(beanName, mbd);
}

下面进一步说明一下基于工厂方法和基于构造方法创建 bean 对象的过程。如果在配置时使用 factory-method 属性指明了工厂方法,则 Spring 在初始化 IoC 容器时会调用 AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod 方法创建 bean 实例,该方法的实现比较冗长,故不在此贴出。总结来说,该方法的主要执行流程如下:

  1. 确定当前使用的是静态工厂配置,还是非静态工厂配置;
  2. 基于参数类型和个数确定用于实例化 bean 的工厂方法版本;
  3. 调用工厂方法创建 bean 对象。

其中最复杂的是第二步,因为可能存在多个工厂方法的重载版本,所以需要依据给定或配置的参数个数和类型去解析确定具体使用哪个工厂方法。Spring 会对所有的候选工厂方法按照 public 优先,以及参数个数多的方法优先的原则进行排序,然后逐个比对是否满足当前指定的参数列表,依次确定具体使用哪个工厂方法创建 bean 实例。基于构造方法创建 bean 对象的过程与上述过程大同小异,核心都是基于参数个数和类型确定最终调用的方法版本,不再展开。

需要清楚的一点是,经过上述过程创建的 bean 实例,不管是通过工厂方法还是构造方法,到这里得到 bean 实例也仅仅是一个最初实例,接下去还需要对该实例进行初始化,注入相应的属性值等。如果将此时的 bean 实例看作是一张白纸,那么初始化操作就可以类比在白纸上作画,而颜料就是之前解析得到的 BeanDefinition 对象。Spring 定义了 MergedBeanDefinitionPostProcessor 处理器接口,允许用户在容器执行初始化操作之前对最终的 BeanDefinition 对象进行修改。

步骤二 所做的工作就是应用 MergedBeanDefinitionPostProcessor 处理器,相应的实现位于 AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors 方法中:

1
2
3
4
5
6
7
8
9
10
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
// 获取并遍历所有的后置处理器
for (BeanPostProcessor bp : this.getBeanPostProcessors()) {
// 如果是 MergedBeanDefinitionPostProcessor,则进行应用 postProcessMergedBeanDefinition 方法
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}

对于 singleton 类型对象而言, 步骤三 会提前曝光 bean 实例,Spring 基于该机制尝试自动解决循环依赖问题。循环依赖可能发生在构造方法注入过程中,也可能发生在 setter 方法注入过程中,对于前者来说 Spring 是无法解决的,对于后者则可以通过提前曝光机制达到“先引用,后初始化”的目的,从而巧妙的破解环路。提前曝光机制的实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
boolean earlySingletonExposure = (mbd.isSingleton() // 单例
&& this.allowCircularReferences // 允许自动解决循环依赖
&& this.isSingletonCurrentlyInCreation(beanName)); // 当前 bean 正在创建中
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
// 为避免循环依赖,在完成 bean 实例化之前,将对应的 ObjectFactory 注册到容器中
this.addSingletonFactory(beanName,
// 获取 bean 的提前引用
() -> this.getEarlyBeanReference(beanName, mbd, bean));
}

// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}

说明一下上述方法中几个变量的含义:

  • singletonObjects:用于记录 beanName 和 bean 实例之间的映射关系。
  • singletonFactories:用于记录 beanName 和创建 bean 的工厂 ObjectFactory 对象之间的映射关系。
  • earlySingletonObjects:也是记录 beanName 和 bean 实例之间的映射关系,不同于 singletonObjects,其中记录的 bean 实例在创建过程中就可以通过 getBean 方法获取到。
  • registeredSingletons:用来记录当前所有已注册的 beanName,按照注册顺序存放。

提前曝光也就是在初始化 bean 对象之前曝光该对象,其目的是先创建好对象,再建立依赖关系,将这两步拆分开以破解依赖环路。当初始化一个 bean 对象时,如果引用了另外一个 bean 对象,此时就需要转而去创建并初始化引用的 bean 对象,如果恰好该 bean 对象又引用了之前的 bean 对象就出现了循环依赖。假设我们令第一个 bean 为 A,第二个 bean 为 B,基于这段代码的执行逻辑,B 就可以先给自己类型为 A 的属性注入 A 的实例(这个时候 A 还没有被初始化)然后完成初始化,此时继续回到初始化 A 的逻辑,因为都是单例,所以当 A 完成了初始化之后,B 所引用的 A 对象也就是一个完成了初始化过程的对象,而不是之前的刚刚完成创建还没有注入属性的对象。

步骤四 实现了对上面创建的 bean 实例执行初始化的逻辑,包括 属性注入调用初始化方法 两个步骤。先来分析属性注入的过程,该过程由 AbstractAutowireCapableBeanFactory#populateBean 方法实现(populate,这个词很有想象力~):

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
83
84
85
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 未创建 bean 对象
if (bw == null) {
// 但是存在需要注入的属性
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
} else {
// Skip property population phase for null instance.
return;
}
}

// 调用 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 方法对初始化前的 bean 实例进行处理
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : this.getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}

// 获取 bean 实例的属性值集合
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

// 获取注入类型
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据名称注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
// 根据类型注入
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}

boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

// 应用 InstantiationAwareBeanPostProcessor#postProcessProperties 方法在注入属性之前对属性值进行处理
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : this.getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 兼容已过期的方法
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
// 处理器把属性值处理没了,继续执行属性注入已经没有意义,直接返回
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}

// 依赖检查,对应 dependency-check 属性,该属性已过期
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, pvs);
}

// 执行属性注入
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, pvs);
}
}

上述方法会执行 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 后置处理方法,以实现对完成创建但还未注入属性值的对象进行最后的更改。如果该方法指明不需要执行后续的属性注入过程,则运行到此结束;否则方法会检测当前的注入类型是 byName 还是 byType,并执行对应的注入逻辑获取依赖的属性值。在真正执行注入之前,还会应用 InstantiationAwareBeanPostProcessor#postProcessProperties 处理方法对待注入的属性值执行最后的修改,并依据配置决定是否执行依赖检查,以确保所有的属性都被赋值(这里的赋值是指 BeanDefinition 对象中的属性都有对应的值,而不是指最终 bean 实例的属性是否注入了对应的值)。最后将属性值注入给 bean 实例对应的属性中。

整个流程还是比较清晰的,下面进一步分析基于 name 或 type 解析属性值,以及注入属性值的过程。

  • 基于 name 解析属性值

如果当前注入类型是 byName,则容器会基于 beanName 获取依赖的 bean 实例,并将依赖关系记录到对应的集合中,如果依赖的 bean 未被实例化则需要转而执行实例化。基于 name 解析属性值的过程由 AbstractAutowireCapableBeanFactory#autowireByName 方法实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 获取需要注入的属性名称集合
String[] propertyNames = this.unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
// 当前属性是由容器管理
if (this.containsBean(propertyName)) {
// 获取 bean 实例,如果没有实例化则执行实例化操作
Object bean = this.getBean(propertyName);
// 记录到属性集合中
pvs.add(propertyName, bean);
// 记录 bean 之间的依赖关系
this.registerDependentBean(propertyName, beanName);
} else {
// ... 省略日志打印
}
}
}
  • 基于 type 解析属性值

如果当前注入类型是 byType,则容器会依据属性类型去确定依赖的 bean 实例,并将依赖关系记录到对应的集合中,如果依赖的 bean 未被实例化则需要转而执行实例化。因为类型注入需要有一个推断的过程,所以实现逻辑要复杂很多,位于 AbstractAutowireCapableBeanFactory#autowireByType 方法中:

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
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

TypeConverter converter = this.getCustomTypeConverter();
if (converter == null) {
converter = bw;
}

Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 获取需要注入的属性名称集合
String[] propertyNames = this.unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
// 获取对应的 setter 方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
/*
* 解析指定 beanName 属性所匹配的值,并把解析到的属性存储在 autowiredBeanNames 中,当属性存在多个候选 bean 时,比如:
*
* @Autowired
* private List<A> list
*
* 则会注入找到的所有匹配 A 类型的 bean 实例
*/
Object autowiredArgument = this.resolveDependency(desc, beanName, autowiredBeanNames, converter);
// 记录到属性集合中
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
// 记录 bean 之间的依赖关系
for (String autowiredBeanName : autowiredBeanNames) {
this.registerDependentBean(autowiredBeanName, beanName);
}
autowiredBeanNames.clear();
}
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}

public Object resolveDependency(DependencyDescriptor descriptor,
@Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames,
@Nullable TypeConverter typeConverter) throws BeansException {

// 获取并初始化参数名称探测器
descriptor.initParameterNameDiscovery(this.getParameterNameDiscoverer());
// 支持 java8 的 Optional
if (Optional.class == descriptor.getDependencyType()) {
return this.createOptionalDependency(descriptor, requestingBeanName);
}
// 对应 ObjectFactory 类注入的特殊处理
else if (ObjectFactory.class == descriptor.getDependencyType()
|| ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
// 支持 javax.inject.Provider
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
// 通用处理逻辑
else {
Object result = this.getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
if (result == null) {
result = this.doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}

对于通用处理逻辑而言,Spring 的解析过程如下:

  1. 以确定的 @Value 注解和集合类型进行解析,如果不是这些类型则获取匹配类型的 bean 实例集合;
  2. 如果存在多个匹配项则尝试以优先级配置(比如 Primary 或 Priority)确定首选的 bean 实例,否则无需做推断逻辑;
  3. 检测当前解析得到的 bean 是不是期望的 bean 实例,如果是工厂之类的 bean,则还要继续获取工厂所创建的 bean 实例。
  • 注入属性值

执行到这一步才真正将 bean 的所有属性全部注入到 bean 实例中,之前虽然已经创建了实例,但是属性仍存在于 BeanDefinition 实例中。注入的过程由 AbstractAutowireCapableBeanFactory#applyPropertyValues 方法实现,该方法会将相应属性转换成目标 bean 实例中对应属性的真实类型,并注入到对应属性上:

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}

if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(this.getAccessControlContext());
}

MutablePropertyValues mpvs = null;
// 记录待执行类型转换的属性值
List<PropertyValue> original;

if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 之前已经完成了类型转换,直接注入
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
} catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
} else {
original = Arrays.asList(pvs.getPropertyValues());
}

TypeConverter converter = this.getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 创建属性值解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// 遍历属性值,执行类型转换
for (PropertyValue pv : original) {
// 已经转换过
if (pv.isConverted()) {
deepCopy.add(pv);
}
// 未转换,执行类型转换
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName)
&& !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
// 判定可以转换,执行转换
if (convertible) {
convertedValue = this.convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
// 转换后的值等于原始值
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
// 转换后的类型不是集合和数组类型
else if (convertible && originalValue instanceof TypedStringValue
&& !((TypedStringValue) originalValue).isDynamic()
&& !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
// 未解析完全(对应集合或数组类型),标记需要继续解析
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}

// 标记已经全部转换完成
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}

// 设置属性值,深拷贝
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
} catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}

完成了属性注入过程,接下来容器会执行指定的 init-method 方法。不过,Spring 并不是单纯的调用一下对应的初始化方法,在 AbstractAutowireCapableBeanFactory#initializeBean 实现中主要做了 4 件事情:

  1. 激活 bean 实现的 Aware 类,包括 BeanNameAware、BeanClassLoaderAware,以及 BeanFactoryAware;
  2. 应用 BeanPostProcessor#postProcessBeforeInitialization 方法,实现初始化前置处理;
  3. 调用用户自定义的 init-method 方法,以及常用的 InitializingBean#afterPropertiesSet 方法;
  4. 应用 BeanPostProcessor#postProcessAfterInitialization 方法,实现初始化后置处理。

方法实现如下:

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
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 1. 激活 bean 实现的 Aware 类:BeanNameAware, BeanClassLoaderAware, BeanFactoryAware
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}

// 2. 应用 BeanPostProcessor#postProcessBeforeInitialization 方法
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

// 3. 调用用户自定义的 init-method 方法,以及常用的 afterPropertiesSet 方法
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex);
}

// 应用 BeanPostProcessor#postProcessAfterInitialization 方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

到此,一个 bean 也就基本实例化完成了。在返回该 bean 实例之前,为了确保正确性,Spring 会基于依赖关系检测当前 bean 所依赖的 bean 实例是否都已经实例化完成( 步骤五 ),如果存在未完成实例化的 bean 则说明配置存在问题,需要抛出异常。这种情况通常都是循环依赖所导致的,这对于使用 Spring 的正确运行而言是一个极大的隐患,所以需要确保所有实例化的 bean 都完成了对象的创建和初始化过程,否则应用不应该正常启动。

对于配置了 destroy-method 属性的 bean,或者该 bean 实现了 DisposableBean 或 DestructionAwareBeanPostProcessor 接口,那么在返回 bean 实例之前,Spring 还需要为该 bean 注册销毁机制( 步骤六 )。以常用的 DisposableBean 接口为例,当执行销毁一个实现了该接口的 bean 实例时,相应的 DisposableBean#destroy 方法会被调用。对应的注册过程由 AbstractBeanFactory#registerDisposableBeanIfNecessary 方法实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? this.getAccessControlContext() : null);
if (!mbd.isPrototype() && this.requiresDestruction(bean, mbd)) {
// singleton 类型
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors, DisposableBean interface, custom destroy method.
this.registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), acc));
}
// 其它作用域
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), acc));
}
}
}

以 singleton 类型为例,如果一个 bean 需要注册销毁机制,那么 Spring 会以 beanName 为 key,以包装销毁逻辑的 DisposableBeanAdapter 对象为 value 记录到 DefaultSingletonBeanRegistry#disposableBeans 属性中。当相应的 bean 被销毁时,容器就会尝试获取对应的 DisposableBeanAdapter 实例,并执行销毁逻辑。

类型检查和转换

在调用 BeanFactory#getBean(String name, Class<T> requiredType) 方法获取 bean 实例,或者做类型检查时,可以指定期望的 bean 类型。如果指定该参数则容器在创建和初始化 bean 对象的最后一步需要执行类型校验,并尝试将 bean 实例转换成期望类型,实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 如果要求做类型检查,则检查 bean 的实际类型是否是期望的类型,对应 getBean 时指定的 requireType
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 执行类型转换,转换成期望的类型
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
} catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}

转换的过程还是比较复杂的,鉴于本篇已经写的够长了,就不再展开啦。

总结

至此,我们已经完成了对 BeanFactory#getBean 完整过程的分析。回顾过去这几篇文章,我们探究了容器加载、解析配置文件得到 BeanDefinition 实例,并基于该实例创建、初始化得到目标 bean 实例的过程。虽然 Spring 暴露的使用方式只有短短几行,但是背后却暗藏着十分复杂的逻辑。实际中我们一般不会直接使用 BeanFactory 操作容器,使用更多的是 ApplicationContext 对象,下一篇我们将继续探究基于 ApplicationContext 的 bean 的加载和初始化过程。

参考

  1. Spring 源码深度解析