1. 目录

[TOC]

2. 说明

前面ApplicationContex刷新流程中我们已经走到了beanFactory.preInstantiateSingletons(),初始化单例bean依赖于解析得到的BeanDefinition,且这是容器最后一步复杂的操作了

这里需要提一下,前面与Bean生命周期相关的BeanPostPocessor已经出初始化成了Bean,因为这涉及到全局的,因此提前初始化,这里需要初始化的都是一般的Bean了

3. 依赖关系

DefaultlistableBeanFactory初始化单例主要逻辑是在AbstractBeanFactory中,其依赖关系如下图:

7003997472bf8ded76ddc41269f216ad

AbstractBeanFactory在这里继承了DefalultSingletonBeanRegistryDefalultSingletonBeanRegistry主要维护了单例bean的三级缓存逻辑

4. 源码解析

4.1. DefaultListableBeanFactory#preInstantiateSingletons() 初始化单例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
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}

//拿到所有的BeanName
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

for (String beanName : beanNames) {

//获取到BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

//满足非抽象类、单例、非懒加载才执行
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断是否为FactoryBean,因为FactoryBean实际上要getObject才能真正初始化bean
//if里就是多了一层判断,一般普通的bean就直接走else流程,
if (isFactoryBean(beanName)) {
//获取到FactoryBean的容器实例
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
//安全相关,不分析,直接走else
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
//是不是需要提前初始化
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//是否需要在初始化阶段初始化内部真正的bean
if (isEagerInit) {
getBean(beanName);
}
}
}

else {
//获取容器Bean
getBean(beanName);
}
}
}

//这里走的时候已经初始化完成了单例bean了,这里主要做SmartInitializingSingleton钩子函数的后处理
//若有需要也可以实现 SmartInitializingSingleton 接口做bean完成初始化了的事情
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

4.2. getBean() 获取bean

虽然此方法为getBean,但是其中包含了从容器三层缓存中拿,没有的话就会调用创建逻辑创建

getBean方法在 AbstractBeanFactory中执行,是DefaultListableBeanFactory的父类,主要做bean相关的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// DefaultListableBeanFactory -> AbstractBeanFactory
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}

@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}

@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
throws BeansException {

return doGetBean(name, requiredType, args, false);
}

上面三个getBean()方法实际上差不多,都会调用到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
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {

//获取到beanName
//这里就是转换name的大小写等,获取别名下的真实名
String beanName = transformedBeanName(name);
Object bean;

//从三级缓存中获取bean
//第一次进来的时候还没有创建单例Bean,返回的数据为空,后续有数据了返回的就有数据了,就不会再走创建流程
//这里是第一种获取单例的方法, 其中不包括初始化bean
Object sharedInstance = getSingleton(beanName);

//一般我们没拿到数据,会走else逻辑
//若拿到了单例bean,则组装返回
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类型,即将FatoryBean内部的需要实例的bean真正的做实例化(这是第二处处理FactoryBean)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {

//正在创建原型实例则报错
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

//这里是从父容器中去拿,比如springmvc容器没拿到会从spring容器中拿,进去了逻辑和getBean是一样的
//暂时不考虑,直接走通了带父级的也就通了
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}


//是否只是检查类,如果只是检查,就不做优化
if (!typeCheckOnly) {
//优化创建逻辑,加一个缓存,暂时可以不考虑
markBeanAsCreated(beanName);
}

try {

//获取BeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//校验BeanDefinition
checkMergedBeanDefinition(mbd, beanName, args);

//处理@DependsOn依赖,依赖于别的bean则需要先初始化别的bean,再回来初始化自己
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//加入依赖map,又是一个缓存,可以不考虑
registerDependentBean(dep, beanName);
try {
//初始化被依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

//是单例的就走创建单例,会去三级缓存中拿
if (mbd.isSingleton()) {
//获取单例的bean,注意匿名内部类,覆写的是 getObject()方法,调用的时候执行ceateBean,相当于先调用缓存查找,没查找到就创建Bean
//这里是第二种获取单例bean,没有会创建并存储到一级缓存,移除二三层
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//异常了就清楚单例缓存
destroySingleton(beanName);
throw ex;
}
});
//处理好FactoryBean的相关信息,然后就返回了
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//原型的就直接走原型模式创建
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//其他类型的如 Request session globalSession,暂时不考虑,主要考虑单例bean
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
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, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(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) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}

// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
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());
}
}
return (T) bean;
}

4.3. getSingleton() 获取单例bean<一>

第一种获取单例bean的方法,主要是处理缓存,不考虑初始化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
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存中获取单例bean
Object singletonObject = this.singletonObjects.get(beanName);

//一级没取到则继续往下
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {

//从二级缓存中获取,这里采用双重检测锁的方案,查询-加锁-查询,
//而且这里加锁后还是又查了一下一级缓存,更保险
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {

//二级缓存中也没有,则查三级缓存,查找了之后加入到二级,从三级中移除
//这里也是循环依赖解决的代码逻辑
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}

4.4. getSingleton() 获取单例bean<二>

获取单例缓存,若没有,则执行getObject()里的创建流程createBean()(由外部覆写的匿名内部类ObjectFactory

此方法和上面不同在于这里会调用创建逻辑,创建好了之后会加入到缓存中,再返回

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
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");

//加锁
synchronized (this.singletonObjects) {

//获取单例bean
Object singletonObject = this.singletonObjects.get(beanName);

//不为空则直接返回了,为空则继续执行创建,
if (singletonObject == null) {
//创建前先校验是否再销毁中,正在销毁容器的话则报错,加入也没意义了
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 + "'");
}

//检查是否正在创建中,正在创建也会报错,比如循环依赖
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//调用获取单例bean的方法,实际调用传入的匿名内部类中的doCreate()方法
//先走create方法创建,完成后再得到结果,创建方法单独开篇文章详解
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
//如果这里报错了则再获取一下做个保底,获取到了则说明在别的地方创建好了,报错就报错,不管了,没有获取到说明真的报错了,就抛异常
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;
}
//不管异常与否都进行校验,并从正在创建的缓存中移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
//这里添加到单例容器中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}

4.5. addSingleton() 添加单例bean到容器中

此处是典型的添加到单例容器中的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
protected void addSingleton(String beanName, Object singletonObject) {
//加锁
synchronized (this.singletonObjects) {
//添加一级缓存
this.singletonObjects.put(beanName, singletonObject);
//从三级缓存中移除
this.singletonFactories.remove(beanName);
//从二级缓存中移除
this.earlySingletonObjects.remove(beanName);
//已经添加注册的beanName,又一个缓存
this.registeredSingletons.add(beanName);
}
}

此处有添加到一级缓存singletonObjects的操作,也有从二级缓存earlySingletonObjects、三级缓存singletonFactories移除的操作。其原因是因为在前面通过 ObjectFactory.getObject()方法的匿名内部类中的createBean会创建三级和二级缓存,而其创建本身并不会删除缓存中的数据,创建直接返回成型的bean,这就相当于二级三级缓存都作为了临时的存储了,但是并没有删除。
而到了这里已经是确定创建bean完成需要加入到一级缓存中了,那么bean肯定已经初始化完成,并且已经放到了一级缓存,那么二级、三级缓存中的数据肯定就是没有用了,因此,在这里将其移除。

4.6. getObjectForBeanInstance()

此处是AbstractAutowireCapableBeanFactory先调用getObjectForBeanInstance(),处理完成通过super.getObjectForBeanInstance()调用AbstraceBeanFactorygetObjectForBeanInstance()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
// AbstractAutowireCapableBeanFactory
@Override
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

//处理创建好的bean,并且加入dependenciesForBeanMap缓存中 ,有啥用未细了解
String currentlyCreatedBean = this.currentlyCreatedBean.get();
if (currentlyCreatedBean != null) {
registerDependentBean(beanName, currentlyCreatedBean);
}
//调用父类的方法
return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}

父类AbstraceBeanFactory

此方法主要处理FactoryBean类型,需要拿到内部的实际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
// AbstraceBeanFactory
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}

//**不是FactoryBean类型,则直接返回了**
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}

Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
//这里拿了一下缓存,有就有,没有就没有
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//从FactoryBean中获取
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}

5. 总结

本节主要讲解获取bean的逻辑,

  1. 首先通过beanName拿到BeanDifinition
  2. 然后去单例缓存中拿bean,若拿到则返回
  3. 再从parent中拿,拿到则返回
  4. 继续从单例缓存中拿,没有拿到则根据匿名内部类的ObjectFactory#getObject()创建bean,创建好了之后存进一级缓存中,再从二三级缓存中删除
  5. 处理好ObjectFactory实例,从内部获取真实的bean,然后返回,

大致流程就是这样

6. 注意事项

此处有两个getSingleton()方法,但是其功能不一样

  • protected Object getSingleton(String beanName, boolean allowEarlyReference)
    只是单纯的查询缓存,一级缓存查到了则返回,没查到就继续查二三级缓存。
    若三级缓存中查到了数据则处理之后交给二级缓存
  • public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)
    会查询单例缓存,没有查询到也不会从二三级取查,而直接使用传入的ObjectFactory,此对象有外部的匿名内部类方法createBean,从而执行创建。
    创建成功后会加入一级缓存,而从二三级缓存中删除