抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Spring源码分析-getBean

前言

​ 接着 Spring IoC:finishBeanFactoryInitialization详解,我们正式开始学习获取 bean 实例方法,该方法是 Spring 最核心的方法。

​ 单击 preInstantiateSingletons 方法里的 getBean(beanName) 代码,进入该方法。

流程图

getBean

实例化Bean的核心方法

1
2
3
4
5
6
7
8
/**
* 创建实例的主要入口
*/
@Override
public Object getBean(String name) throws BeansException {
// 获取name对应的bean实例,如果不存在,则创建一个
return doGetBean(name, null, null, false);
}

doGetBean

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
184
185
186
187
188
189
190
191
192
193
/**
* 实例化bean的主要方法
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//根据name拿到bean的名称
// 1.解析beanName,主要是解析别名、去掉FactoryBean的前缀“&”
final String beanName = transformedBeanName(name);
Object bean;

// 2.尝试从缓存中获取beanName对应的实例
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
// 3.如果beanName的实例存在于缓存中
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (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接口的调用入口
// 3.1 返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
//如果singletonObjects缓存里面没有,则走下来
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//如果是scope 是Prototype的,校验是否有出现循环依赖,如果有则直接报错
// 4.scope为prototype的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常
// 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// 5.获取parentBeanFactory
//检查是否存在父类容器的定义 一般是没有的
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
// 5.1 如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 5.2 将别名解析成真正的beanName
String nameToLookup = originalBeanName(name);
// 5.3 尝试在parentBeanFactory中获取bean对象实例
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);
}
}

if (!typeCheckOnly) {
// 6.如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
markBeanAsCreated(beanName);
}

try {
//父子BeanDefinition合并
// 7.根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 7.1 检查MergedBeanDefinition是否是抽象的
checkMergedBeanDefinition(mbd, beanName, args);

// 8.拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 8.1 遍历当前bean依赖的bean名称集合
for (String dep : dependsOn) {
// 8.2 检查dep是否依赖于beanName,即检查是否存在循环依赖
if (isDependent(beanName, dep)) {
// 8.3 如果是循环依赖则抛异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 8.4 将dep和beanName的依赖关系注册到缓存中
registerDependentBean(dep, beanName);
try {
// 8.5 获取dep对应的bean实例,如果dep还没有创建bean实例,则创建dep的bean实例
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

//着重看,大部分是单例的情况
// 9.针对不同的scope进行bean的创建
// Create bean instance.
if (mbd.isSingleton()) {
//获取单例的实例,单例的核心入口
// 9.1 scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
sharedInstance = getSingleton(beanName, () -> {
try {
// 9.1.1 创建Bean实例,调用实例化的核心方法
return 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.
destroySingleton(beanName);
throw ex;
}
});
//该方法是FactoryBean接口的调用入口
// 9.1.2 返回beanName对应的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// 9.2 scope为prototype的bean创建
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 9.2.1 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
//将正在实例化的bean加入prototypesCurrentlyInCreation用来阻断循环依赖
beforePrototypeCreation(beanName);
// 9.2.2 创建Bean实例
prototypeInstance = createBean(beanName, mbd, args);
} finally {
// 9.2.3 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
// 9.2.4 返回beanName对应的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 9.3 其他scope的bean创建,可能是request之类的
// 9.3.1 根据scopeName,从缓存拿到scope实例
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 {
// 9.3.2 其他scope的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
Object scopedInstance = scope.get(beanName, () -> {
// 9.3.3 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
try {
// 9.3.4 创建bean实例
return createBean(beanName, mbd, args);
} finally {
// 9.3.5 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
});
// 9.3.6 返回beanName对应的实例对象
bean = 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) {
// 如果创建bean实例过程中出现异常,则将beanName从alreadyCreated缓存中移除
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 10.检查所需类型是否与实际的bean对象的类型匹配
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 10.1 类型不对,则尝试转换bean类型
T convertedBean = 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());
}
}
// 11.返回创建出来的bean实例对象
return (T) bean;
}

getObjectForBeanInstance

获取给定bean实例的对象,或者实例本身或FactoryBean创建的对象

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
/**
* 获取给定bean实例的对象,或者实例本身或FactoryBean创建的对象
*/
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

// Don't let calling code try to dereference the factory if the bean isn't a factory.
//1. 如果name是以 “&” 号开头的进入方法并返回实例
if (BeanFactoryUtils.isFactoryDereference(name)) {
//1.1 如果实现了NullBean直接返回实例
if (beanInstance instanceof NullBean) {
return beanInstance;
}
//1.2 如果beanInstance不是FactoryBean,则直接报错
if (!(beanInstance instanceof FactoryBean)) {
//抛出异常报错
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
//1.3 如果mbd不为空则设置mbd的isFactoryBean为true
if (mbd != null) {
mbd.isFactoryBean = true;
}
//2. 返回实例
return beanInstance;
}


// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 2. 如果beanInstance不是FactoryBean(也就是普通bean),则直接返回beanInstance
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}

// 3.走到这边,代表beanInstance是FactoryBean,但name不带有“&”前缀,表示想要获取的是FactoryBean创建的对象实例
Object object = null;
// 4.如果mbd不为空则设置mbd的isFactoryBean为true
if (mbd != null) {
mbd.isFactoryBean = true;
} else {
//5. 如果mbd为空,则尝试从factoryBeanObjectCache缓存中获取该FactoryBean创建的对象实例
object = getCachedObjectForFactoryBean(beanName);
}
//如果缓存中没有拿不到
if (object == null) {
// 6. 只有beanInstance是FactoryBean才能走到这边,因此直接强转
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
//7. 检查beanDefinitionMap中是否有beanName
if (mbd == null && containsBeanDefinition(beanName)) {
// 7.1 mbd为空,但是该bean的BeanDefinition在缓存中存在,则获取该bean的MergedBeanDefinition
mbd = getMergedLocalBeanDefinition(beanName);
}
// 8. mbd是否是合成的(这个字段比较复杂,mbd正常情况都不是合成的,也就是false,有兴趣的可以自己查阅资料看看)
boolean synthetic = (mbd != null && mbd.isSynthetic());
//重点看
// 9.从FactoryBean获取对象实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
// 10.返回对象实例
return object;
}

isFactoryDereference

来到BeanFactoryUtils类

是否是FactoryBean,检查name不为空并且name是以 “&” 符号开头的

1
2
3
4
5
6
7
8
/**
* 检查是否是FactoryBean
*/
public static boolean isFactoryDereference(@Nullable String name) {
//如果name不为空并且name是以 “&” 符号开头的
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}

getObjectFromFactoryBean

从FactoryBean中获取对象

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
/**
* Obtain an object to expose from the given FactoryBean.
* 从FactoryBean中获取对象
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 1.如果是单例,并且已经存在于单例对象缓存中
//工厂bean是单例的并且singletonObjects的缓存中存在beanName
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 2.从FactoryBean创建的单例对象的缓存中获取该bean实例
Object object = this.factoryBeanObjectCache.get(beanName);
//如果为null
if (object == null) {
// 3.调用FactoryBean的getObject方法获取对象实例
object = 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)
//4. 再次检查factoryBeanObjectCache是否存在
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
// 5.如果该beanName已经在缓存中存在,则将object替换成缓存中的
if (alreadyThere != null) {
object = alreadyThere;
} else {
if (shouldPostProcess) {
//6. 检查beanName是否正在创建如果正在创建直接返回正在创建的实例
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
//7. 将正在创建的Bean加入到inCreationCheckExclusions中
//在这个集合里面的bean都是正在实例化的bean
//如果重复添加就会报错,防止构造方法循环依赖
beforeSingletonCreation(beanName);
try {
//提前暴露bean
//8. 对bean实例进行后置处理,执行所有已注册的BeanPostProcessor的postProcessAfterInitialization方法
object = postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
} finally {
//9. Bean创建完成从inCreationCheckExclusions中删除beanName
afterSingletonCreation(beanName);
}
}
//singletonObjects的缓存中存在beanName
if (containsSingleton(beanName)) {
//10. 把实例缓存到factoryBeanObjectCache map中,这个是单独缓存FactoryBean类型实例的map
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
//11. 返回object对象实例
return object;
}
} else {
//缓存中不存在bean
//12.调用FactoryBean的getObject方法获取对象实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
//提前暴漏bean
//13. 对bean实例进行后置处理,执行所有已注册的BeanPostProcessor的postProcessAfterInitialization方法
object = postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
//14. 返回bean的实例
return object;
}
}
doGetObjectFromFactoryBean

调用getObject获取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
/**
* 调用getObject获取bean实例
*/
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {

Object object;
// 1.调用FactoryBean的getObject方法获取bean对象实例
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
// 1.1 带有权限验证的
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
// 1.2 不带权限
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.
// 2.getObject返回的是空值,并且该FactoryBean正在初始化中,则直接抛异常,不接受一个尚未完全初始化的FactoryBean的getObject返回的空值
if (object == null) {
//2.1 如果该Bean 正在实例化说明出现了循环依赖直接报错
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
//2.2 如果第一次实例化为空 转换为NullBean
object = new NullBean();
}
//3.返回创建好的bean对象实例
return object;
}

​ 很简单的方法,就是直接调用 FactoryBean 的 getObject 方法来获取到对象实例。

​ 细心的同学可以发现,该方法是以 do 开头, do 开头的方法是最终进行实际操作的方法,例如本方法就是 FactoryBean 最终实际进行创建 bean 对象实例的方法。

postProcessObjectFromFactoryBean

是一个扩展点,使用BeanPostProcessor对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
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}

/**
* 是一个扩展点
* 执行BeanPostProcessor的postProcessAfterInitialization接口
*/
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
// 1.遍历所有注册的BeanPostProcessor实现类,调用postProcessAfterInitialization方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 2.在bean初始化后,调用postProcessAfterInitialization方法
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
// 3.如果返回null,则不会调用后续的BeanPostProcessors
return result;
}
result = current;
}
return result;
}

​ 这边走的是 AbstractAutowireCapableBeanFactory 里的方法。通过前面的介绍,我们知道创建的 BeanFactory 为 DefaultListableBeanFactory,而 DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory,因此这边会走 AbstractAutowireCapableBeanFactory 的重写方法。

markBeanAsCreated

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
/**
* 清除alreadyCreated中的缓存

*/
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
// 1.如果alreadyCreated缓存中不包含beanName
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
// 2.将beanName的MergedBeanDefinition从mergedBeanDefinitions缓存中移除,
// 在之后重新获取MergedBeanDefinition,避免BeanDefinition在创建过程中发生变化
clearMergedBeanDefinition(beanName);
// 3.将beanName添加到alreadyCreated缓存中,代表该beanName的bean实例已经创建(或即将创建)
this.alreadyCreated.add(beanName);
}
}
}
}

/**
* 移除指定bean的合并bean定义,在下次访问时重新创建它
* @param beanName the bean name to clear the merged definition for
*/
protected void clearMergedBeanDefinition(String beanName) {
//从mergedBeanDefinitions中获取BeanDefinition
RootBeanDefinition bd = this.mergedBeanDefinitions.get(beanName);
if (bd != null) {
//设置 stale属性为true
bd.stale = true;
}
}

​ 这边会将 beanName 对应的 MergedBeanDefinition 移除,然后在之后的代码重新获取,主要是为了使用最新的 MergedBeanDefinition 来进行创建操作。

isDependent

循环依赖检查

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
/**
* 循环依赖检查
*/
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
// 已经检查过的直接跳过
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
// 1.将别名解析为真正的名称
String canonicalName = canonicalName(beanName);
// 2.拿到依赖canonicalName的beanName集合
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
// 3.如果dependentBeans为空,则两者必然还未确定依赖关系,返回false
if (dependentBeans == null) {
return false;
}
// 4.如果dependentBeans包含dependentBeanName,则表示两者已确定依赖关系,返回true
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
// 5.循环检查,即检查依赖canonicalName的所有beanName是否存在被dependentBeanName依赖的(即隔层依赖)
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
//加入到set
alreadySeen.add(beanName);
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}

​ 这边引入了一个缓存 dependentBeanMap:beanName -> 所有依赖 beanName 对应的 bean 的 beanName 集合。内容比较简单,就是检查依赖 beanName 的集合中是否包含 dependentBeanName,隔层依赖也算。例如:A 依赖了 B,B 依赖了 C,则 A 也算依赖了 C。

registerDependentBean

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
/**
* Register a dependent bean for the given bean,
* to be destroyed before the given bean is destroyed.
* 注册依赖的bean和bean name的映射关系
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
// 1.解析别名
String canonicalName = canonicalName(beanName);

synchronized (this.dependentBeanMap) {
//2. 拿到依赖canonicalName的beanName集合
//3.将dependentBeanName添加到依赖canonicalName的beanName集合中
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
// 5.如果dependentBeans包含dependentBeanName,则表示依赖关系已经存在,直接返回
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
//4.如果依赖关系还没有注册,则将两者的关系注册到dependentBeanMap和dependenciesForBeanMap缓存
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}

​ 这边又引入了一个跟 dependentBeanMap 类似的缓存,dependenciesForBeanMap:beanName -> beanName 对应的 bean 依赖的所有 bean 的 beanName 集合。

​ 这两个缓存很容易搞混,举个简单例子:例如 B 依赖了 A,则 dependentBeanMap 缓存中应该存放一对映射:其中 key 为 A,value 为含有 B 的 Set;而 dependenciesForBeanMap 缓存中也应该存放一对映射:其中 key 为:B,value 为含有 A 的 Set。

getSingleton

针对不同的scope进行bean的创建

入口代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//获取单例的实例,单例的核心入口
// 9.1 scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
sharedInstance = getSingleton(beanName, () -> {
try {
// 9.1.1 创建Bean实例,调用实例化的核心方法
return 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.
destroySingleton(beanName);
throw ex;
}
});
代码解析
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
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* 返回一个实例化的单例对象,如果没有实例化就进行实例化
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 1.加锁,避免重复创建单例对象
synchronized (this.singletonObjects) {
// 2.首先检查beanName对应的bean实例是否在缓存中存在,如果已经存在,则直接返回
Object singletonObject = this.singletonObjects.get(beanName);
//第一次调用必定为空
// 3.beanName对应的bean实例不存在于缓存中,则进行Bean的创建
if (singletonObject == null) {
// 4.当bean工厂的单例处于destruction状态时,不允许进行单例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!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 5.创建单例前的操作
//把beanName添加到singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean
beforeSingletonCreation(beanName);
boolean newSingleton = false;
// suppressedExceptions用于记录异常相关信息
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 6.执行singletonFactory的getObject方法获取bean实例
//如果这里有返回值,就代表这个bean已经结束创建了,已经完全创建成功
//调到lamda表达式的createBean(beanName, mbd, args);的方法
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;
}
// 7.创建单例后的操作
//bean创建完成后singletonsCurrentlyInCreation要删除该bean
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 8.如果是新的单例对象,将beanName和对应的bean实例添加到缓存中(singletonObjects、registeredSingletons)
//创建对象成功时,把对象缓存到singletonObjects缓存中,bean创建完成时放入一级缓存
addSingleton(beanName, singletonObject);
}
}
// 9.返回创建出来的单例对象
return singletonObject;
}
}
beforeSingletonCreation&afterSingletonCreation

添加正在实例化的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
/**
* Callback before singleton creation.
* <p>The default implementation register the singleton as currently in creation.
* 添加正在实例化的bean
* 如果再次添加一个存在的就会直接报错
* 标识正在创建的bean
*/
protected void beforeSingletonCreation(String beanName) {
// 把beanName添加到singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean
// 先校验beanName是否为要在创建检查排除掉的(inCreationCheckExclusions缓存),如果不是,
// 则将beanName加入到正在创建bean的缓存中(Set),如果beanName已经存在于该缓存,会返回false抛出异常(这种情况出现在构造器的循环依赖)
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}


/**
* Callback after singleton creation.
* <p>The default implementation marks the singleton as not in creation anymore.
* 完成实例化从inCreationCheckExclusions中删除实例化完成的beanName
*/
protected void afterSingletonCreation(String beanName) {
// 先校验beanName是否为要在创建检查排除掉的(inCreationCheckExclusions缓存),如果不是,
// 则将beanName从正在创建bean的缓存中(Set)移除,如果beanName不存在于该缓存,会返回false抛出异常
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}

​ inCreationCheckExclusions 是要在创建检查排除掉的 beanName 集合,正常为空,可以不管。这边主要是引入了 singletonsCurrentlyInCreation 缓存:当前正在创建的 bean 的 beanName 集合。在 beforeSingletonCreation 方法中,通过添加 beanName 到该缓存,可以预防出现构造器循环依赖的情况。

为什么无法解决构造器循环依赖?

​ 我们之前在 Spring IoC:finishBeanFactoryInitialization详解 中的代码块getSingleton 提过,getSingleton 方法是解决循环引用的核心代码。解决逻辑的第一句话:“我们先用构造函数创建一个 “不完整” 的 bean 实例”,从这句话可以看出,构造器循环依赖是无法解决的,因为当构造器出现循环依赖,我们连 “不完整” 的 bean 实例都构建不出来。Spring 能解决的循环依赖有:通过 setter 注入的循环依赖、通过属性注入的循环依赖。

addSingleton

将实例化完成的单例对象添加到单例对象缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons.
* 将实例化完成的单例对象添加到单例对象缓存
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 1.添加到单例对象缓存,添加进一级缓存
this.singletonObjects.put(beanName, singletonObject);
//2.将单例工厂缓存移除(已经不需要),删除三级缓存
this.singletonFactories.remove(beanName);
//3.将早期单例对象缓存移除(已经不需要),删除二级缓存
this.earlySingletonObjects.remove(beanName);
// 4.添加到已经注册的单例对象缓存
this.registeredSingletons.add(beanName);
}
}

beforePrototypeCreation&afterPrototypeCreation

使用prototypesCurrentlyInCreation 来阻断prototype的循环依赖

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
/**
* Callback before prototype creation.
* <p>The default implementation register the prototype as currently in creation.
* 将正在实例化的bean加入prototypesCurrentlyInCreation
* 用来阻断循环依赖
*/
@SuppressWarnings("unchecked")
protected void beforePrototypeCreation(String beanName) {
// 1.拿到当前线程中正在创建的prototype的bean的beanName集合
Object curVal = this.prototypesCurrentlyInCreation.get();
// 2.如果为空,则将ThreadLocal设置成当前的beanName
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
// 3.如果不为空,并且是String类型,则代表目前只有一个beanName,将之前和当前的一起封装成Set<String>,设置到ThreadLocal中
} else if (curVal instanceof String) {
Set<String> beanNameSet = new HashSet<>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);

// 4.如果不为空,并且不是String,则必然是Set<String>类型,将当前的beanName加到Set中去
} else {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.add(beanName);
}
}



/**
* Callback after prototype creation.
* <p>The default implementation marks the prototype as not in creation anymore.
* 创建成功后从prototypesCurrentlyInCreation移除正在创建的bean
*/
@SuppressWarnings("unchecked")
protected void afterPrototypeCreation(String beanName) {
// 1.拿到当前线程中正在创建的prototype的bean的beanName集合
Object curVal = this.prototypesCurrentlyInCreation.get();
// 2.如果是String类型,则代表目前只有一个beanName,则直接移除
if (curVal instanceof String) {
this.prototypesCurrentlyInCreation.remove();
// 3.如果是Set类型,则从Set从移除beanName
} else if (curVal instanceof Set) {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.remove(beanName);
if (beanNameSet.isEmpty()) {
this.prototypesCurrentlyInCreation.remove();
}
}
}

​ 该方法和代码块beforeSingletonCreation&afterSingletonCreation的两个方法类似。主要是在进行 bean 实例的创建前,将 beanName 添加到 prototypesCurrentlyInCreation 缓存;bean 实例创建后,将 beanName 从 prototypesCurrentlyInCreation 缓存中移除。这边 prototypesCurrentlyInCreation 存放的类型为 Object,在只有一个 beanName 的时候,直接存该 beanName,也就是 String 类型;当有多个 beanName 时,转成 Set 来存放。

总结

​ 本文介绍了获取 bean 实例的大部分内容,包括先从缓存中检查、 FactoryBean 的 bean 创建、实例化自己的依赖(depend-on 属性)、创建 bean 实例的前后一些标记等,在下篇文章中,将解析创建 bean 的内容。

评论