BeanFactory getBean源码分析

初始BeanFactory

Spring中,如果我们需要从IOC容器中获取一个对象,在不考虑自动注入的场景,可以通过调用BeanFactory#getBean(String)方法。

这个方法不但承担了从容器中取出已创建好的对象这一个职责,容器在启动的时候,依次初始化所有需要实例化的对象时,也调用了这个对象,所以我们可以判断这个方法应该有两个功能:

  1. 如果容器中存在该对象,则直接返回
  2. 如果容器中不存在该对象,则创建

其中第一点的实现方式很容易猜到,应该是有一个Map对象,其中存储了beanNamebean的映射关系,在调用getBean方法时,从Map中查询,如果存在该对象,则直接返回。

所以本文主要分析第二种情况,当bean不存在时,是如何进行初始化的。

为了更加深入理解bean初始化的过程,本文还会解释如下几个问题,读者可以带着这几个问题进行阅读:

  1. Spring支持的扩展接口一文中提到的跟bean初始化相关的扩展接口是如何实现的?
  2. 如果两个bean 循环引用的情况如何处理?
  3. 如果两个bean互相依赖(depend-on)如何处理?
  4. SingletonPrototype在实现上的差别是什么?

过程分析

BeanFactory#getBean(String)方法是在AbstractBeanFactory中实现的,进入源码可以发现,getBean方法直接调用了doGetBean方法:

1
2
3
4
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}

getBean方法有许多重载对象,例如通过类型获取对象,这些方法的实现都调用了doGetBean方法,可见doGetBean是该功能的核心实现,接下来具体分析这个方法。

doGetBean

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
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {

//这个方法不光是在初始化时候使用,在后期从Context中获取bean也会进入这里
//所以这里传入的name可能是别名之类的名字,需要转化成原始的beanName方便后面统一处理
final String beanName = transformedBeanName(name);
Object bean;

// bean可能已经存在了,那么再这里获取到后就不需要重新创建了
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 可以获取到的情况
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//获取对象,因为可能获取到的是FactoryBean,所以处理一下
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

else {
// 没有获取到的情况,说明需要创建对象
// 可能会遇到循环引用的情况

if (isPrototypeCurrentlyInCreation(beanName)) {
//prototype bean 并发创建抛出异常
throw new BeanCurrentlyInCreationException(beanName);
}

// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//如果当前容器中没有这个bean的定义,而父容器中存在,那就调用父容器的getBean方法返回对象
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}

if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

try {
//合并父类的类定义
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
//如果有依赖对象,那么先初始化以来对象,同样是调用getBean方法
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
//循环依赖的话就直接抛异常了
// 所以两个Bean循环依赖是不允许的,很多面试官喜欢问循环依赖怎么处理,其实他们想问的是循环引用怎么处理。。。
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
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的创建代码
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
//单例的对象在此处被创建
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;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

else if (mbd.isPrototype()) {
//如果是prototype,那就每次都要创建对象
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
//非单例对象在此处被创建
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

else {
// 其他的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 {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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 && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}

在开头提到的四个问题中的第三个:如果两个bean互相依赖(depend-on)如何处理?第67行就可以解释这个问题,如果互相依赖的话,就会直接抛出异常。但是很多面试官都爱问两个bean互相依赖是怎么解决的,我觉得他们大概率是想问循环引用如何解决,所以以后遇到这样的问题需要跟面试官确认清楚。

再看一下109行,这里是对prototypebean进行初始化,可以发现89行也用到了这个方法,89行的createBean将在84行getSingleton方法中被调用,getSingleton方法后面会详细讲,但这里可以确定一点,singletonprototype的对象都是通过createBean方法进行创建的。所以开篇中的最后一个问题,singletonprototype对象在创建时几乎无差别,只是一个需要判断是否存在,存在则直接返回,另一个每次获取时都创建。

这里还有一个RootBeanDefinition类型,对于这个类型不熟悉或者对其加载过程不熟悉的读者请单独补一下这块知识。简单讲这个对象是用来描述一个bean的定义,可以用这个定义来创建对应的bean

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
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' 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<Exception>();
}
try {
// 调用创建对象方法
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;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}

这段代码里面又判断了一次bean是否已经存在,在不存在的情况下,调用入参中的ObjectFactory#getObject,这个对象是在上一步调用getSingleton方法的时候创建的,实现了getObject方法,而调用的正是createBean方法,所以接下来主要讲的就是createBean方法。

createBean是当前类AbstractBeanFactory中定义的抽象方法,需要子类实现,这个方法的唯一实现类是AbstractAutowireCapableBeanFactory,所以我们现在进入AbstractAutowireCapableBeanFactory类中看这个方法的实现。

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
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;

// 解析需要创建的bean的类型
// 并且复制一份RootBeanDefinition以防其在创建对象过程中被动态修改
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}

// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}

try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 给InstantiationAwareBeanPostProcessor 一个机会可以在此处返回代理对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}

//创建对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}

createBean中做了一些准备工作,并且在27行中调用了resolveBeforeInstantiation方法,我们看一下这里面做了什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//循环调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//如果返回的对象不为空,这里需要直接调用applyBeanPostProcessorsAfterInitialization方法,否则就没有机会调用了
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

这里就涉及到开篇的时候提到的第一个问题了,这段代码在实例化bean之前预留了一个扩展点,方便开发者可以注入自定义的InstantiationAwareBeanPostProcessor对象。具体内容可以参考Spring支持的扩展接口一文中InstantiationAwareBeanPostProcessor章节内容。

进入applyBeanPostProcessorsBeforeInstantiation方法看一下,可以发现这里会遍历执行所有的InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation,当返回值不为null的时候,将直接返回这个结果。回到resolveBeforeInstantiation方法后,也会判断返回值是否为null,如果不为null,就会直接循环调用BeanPostProcessor#postProcessAfterInitialization,然后就直接结束bean的创建过程。

doCreateBean 创建bean

好了,分析完resolveBeforeInstantiation方法,我们退回到createBean方法中,接下来看重头戏,第38行的doCreateBean方法

doCreateBean是个大家伙,基本上创建bean的主要流程都在这里了,包括实例化、参数注入、调用各类初始化、aware类型的回调方法等,先把代码贴一下:

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

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建对象,BeanWrapper是对象的一个包装类型
//这里仅仅是创建了对象,相当于只调用了构造方法,并没有后续赋值(例如自动注入)
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;

// 调用所有MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}

// 先将实例化完成的对象放入到缓存中,用来解决循环依赖的问题
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}

Object exposedObject = bean;
try {
//初始化对象(给参数赋值)
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//完成初始化完成后的回调,例如BeanPostProcessorrocessor.postProcessBeforeInitialization等
exposedObject = 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);
}
}

if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
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" +
".");
}
}
}
}

// 如果一个bean在定义时设置了destory方法或者实现了DisposableBean接口的,在此处注册,以便在销毁bean时进行回调
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}

return exposedObject;
}

这里简单讲一下32~49行,其实关键代码就是39行的方法调用addSingletonFactory,这个方法会将实例化完成的对象放入到缓存中,注意这个时候只是实例化完成了对象,对对象的初始化操作还没执行,注释里写了,这么做的目的是解决循环引用,关于这个问题我们后面单独讲,读者先对这块代码有个印象。

下面着重分析三个方法,其余的代码读者可以参考注释自行关注一下,这里就不深入讲了

createBeanInstance 创建实例

createBeanInstance方法通过其名称就可以知道,是用来创建bean实例,相当于执行对象的new,贴一下代码:

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
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
// 确保类(class)已经被加载
Class<?> beanClass = resolveBeanClass(mbd, beanName);

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());
}

if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}

// Shortcut when re-creating the same 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 autowireConstructor(beanName, mbd, null, null);
}
else {
// 无参构造方法实例化
return instantiateBean(beanName, mbd);
}
}

// Candidate constructors for autowiring?
// 判断是使用什么方式进行实例化
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 有参构造方法实例化
return autowireConstructor(beanName, mbd, ctors, args);
}

// No special handling: simply use no-arg constructor.
// 无参构造方法实例化
return instantiateBean(beanName, mbd);
}

进行初始化之前,需要先解析初始化的方式,一般来说调用构造方法分为两类:有参构造无参构造,为什么要分为这两类,因为无参构造比较简单,直接通过反射获取其构造方法并调用就行;但是有参构造会麻烦一点,因为要获取执行构造方法时的参数,这里以无参构造为例进行分析

无参构造

无参构造时,执行了instantiateBean方法,看一下其实现:

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
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
//把获取到的对象包装成BeanWrapper
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}

初始化对象主要调用了InstantiationStrategy#instantiate,这个接口方法只有一个实现,是在SimpleInstantiationStrategy中实现的,贴一下代码:

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
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (bd.getMethodOverrides().isEmpty()) {
// 如果没有方法复写,则通过反射调用构造方法来初始化
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
// 反射得到无参构造方法
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 调用构造方法
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
// 使用CGLIB 创建子类对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}

这里与我们前面猜想的实例化方式基本一致,通过反射获取并执行构造方法。不过比预想的多了一个步骤——需要判断bean定义中是否设置了方法复写,如果需要方法复写,那么只能通过CGLib来创建子类来实现了。

通过CGLib创建子类的代码就不详细看了,感兴趣的读者可以自行阅读。

populateBean 属性装配

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
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();

if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}

// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;

// 回调InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}

if (!continueWithPropertyPopulation) {
return;
}

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
// 通过名称注入(只是把参数名和对象对应起来,并没有实际注入)
autowireByName(beanName, mbd, bw, newPvs);
}

// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 通过类型注入(只是把参数名和对象对应起来,并没有实际注入)
autowireByType(beanName, mbd, bw, newPvs);
}

pvs = newPvs;
}

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

if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//AutowiredAnnotationBeanPostProcessor是InstantiationAwareBeanPostProcessor的子类
// 用来实现@Autowire、@Value等注解的自动注入
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 通过上面建立好的关系,把参数注入到对象中
applyPropertyValues(beanName, mbd, bw, pvs);
}

参数注入的代码不复杂,读者看着上面的代码及注释应该都能阅读下来

initializeBean 初始化实例

调用initializeBean方法时,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
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
// 这个地方执行了三类接口的回调BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//调用BeanPostProcessors.postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
//调用init-method方法
//如果对象实现了InitializingBean接口,则调用afterPropertiesSet方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//调用BeanPostProcessors.postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

bean循环引用

至此,BeanFactorygetBean过程基本分析完成了,开篇的四个问题中还留下最后一个问题:如果两个bean 循环引用的情况如何处理?

代码读完了,有些读者会很疑惑,具体是在哪里解决了循环引用的问题呢?

在揭晓谜底前,我们现在根据已知的情况做一个推断:

假设有A、B两个类,分别持有对方的引用,那么在启动时,假设先处理A类,在A对象实例化完成后,需要进行属性装配时需要获取B对象实例,那么调用BeanFactory#getBean("B")进行获取,那么此时就会开始B类实例的创建,同样的,B类在初始化完成进行装配时,又需要获取A类对象,此时A对象还没创建完成,难道要继续执行创建A对象的过程吗?

非也。上面的前半部分推断是不错的,但是在B实例化完成,需要获取A实例时,已经可以获取到A实例的对象了,而不是需要重新创建一个。我们可以在代码中找到证据:

doGetBean一节中的代码第11行,调用getSingleton方法,我们跟进去看一下,调用了同名重载方法,贴一下其代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从singletonObjects对象中获取bean,如果获取到了,就直接返回
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

singletonFactories是一个Map,看变量名称就可以知道是用来保存单例对象的工厂,key是beanName,value就是对象实例工厂,获取bean的时候会尝试获取工厂并创建bean,那么这个工厂是在哪里放入的呢?

其实我们之前已经提到过这个点了,[doCreateBean 创建bean](#doCreateBean 创建bean)小节中,doCreateBean方法第31行之后的部分,在bean对象被实例化完成后,就已经把获取对象的工厂放入了,具体执行的代码是在addSingletonFactory方法中,注入调用addSingletonFactory方法时传入的最后一个参数,实现了ObjectFactory#getObject方法,实则调用了getEarlyBeanReference方法。

贴一下getEarlyBeanReference方法的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
if (exposedObject == null) {
return null;
}
}
}
}
return exposedObject;
}

忽略掉中间执行BeanPostProcessor的那段代码,就可以发现,直接将当前的bean返回了,也就是已经实例化完成,但尚未属性注入的对象。

至此,就已经能回答循环引用的处理方式这个问题了。

如果这篇文章对你有帮助,可以请作者喝杯咖啡~