bean的创建过程及循环依赖的解决方式

这篇文章主要讲 Spring bean 的创建过程,以及 Spring 为什么要用三级缓存来解决循环依赖的。原本是打算写 Spring 的启动过程,边读边写,断断续续快半年,内容实在太多,于是打算拆成若干个文章,此是第一篇基础。

首先奉上bean创建过程的大流程图,文章结尾还有循环依赖的另一个流程图。
bean创建流程图

三级缓存和其它较重要的变量

首先我们有个基本概念,Spring 使用三级缓存来创建 bean、解决循环依赖,三级缓存其实就是三个 Map。

缓存 说明
一级 用于存放可以使用的成品bean
二级 用于存放半成品bean,这些bean仅仅刚被创建,没有进行填充属性和实例化,用于解决循环依赖
三级 存放bean工厂对象,用于生产半成品的bean并放入第二级缓存,用于解决循环依赖

这些变量都在 DefaultSingletonBeanRegistry类下,还有其他变量,如用于标记哪些 bean 正在创建中的集合。
在这还有个 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 在  类下
// 一级缓存,存储所有创建好了的单例 bean
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

// 三级缓存
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

// 二级缓存,完成实例化,但还未进行属性注入和初始化的对象
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

/** Set of registered singletons, containing the bean names in registration order. */
// 暂时未理解此变量的用意,这篇文章中也无需关注
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

// 标记现在正在创建的bean
/** Names of beans that are currently in creation. */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));

/** Names of beans currently excluded from in creation checks. */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));



// dependentBeanName 依赖 beanName
// 注册依赖关系,维护了两个map,每个bean分别依赖了谁,和被谁依赖
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);

synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}

synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
代码块0 创建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
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
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

final String beanName = transformedBeanName(name);
Object bean;

// 检查缓存中的bean, 见代码块1
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = 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);
}
}

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) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

// Create bean instance.
if (mbd.isSingleton()) {
// 在这开始创建 bean 了,见代码块2
sharedInstance = getSingleton(beanName, () -> {
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()) {
// 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);
}

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, () -> {
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) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
代码块1 解决循环依赖的核心

从三个缓存中寻找 bean,一级缓存找不到,就去二级找,二级也找不到就去三级找。入参 allowEarlyReference 用于决定是否允许在第三级缓存中寻找。

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
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// 如果一级缓存中为空,且该bean没有正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 尝试从二级缓存中找,处于该缓存中的bean,已经完成实例化,但未进行属性注入
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果二级缓存也没有并允许提前引用的话
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 从三级缓存中拿到工厂,通过工厂获取 bean ,删除三级缓存,添加 bean 到二级缓存中
// 也就是三级缓存升级为二级缓存!
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
代码块2 创建bean前后的一些操作

主要有以下流程:

  • 如果一级缓存里有bean,直接返回。
  • 未创建,标记此bean在创建中。
  • 创建 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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) {
// 这个方法很简单,就是在创建bean之前,把它放入singletonsCurrentlyInCreation 中,标记这个 bean 正在创建,如果该bean已存在了,抛出异常
beforeSingletonCreation(beanName);
boolean newSingleton = false;
// 是否抑制异常,用于决定如果有异常,是抛出去还是放在suppressedExceptions中(不是很重要)
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 调用传过来的方法 (即 createBean(beanName, mbd, args) ) 见代码块4
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;
}
// 此方法也很简单,将 singletonsCurrentlyInCreation 容器中对应的 bean 移除掉
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 如果是个新的bean,添加到一级缓存中,见代码块3
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
代码块3 将bean添加到一级缓存

这是将 bean 添加到一级缓存,同时移除二三级缓存,逻辑很简单。

1
2
3
4
5
6
7
8
9
10
11
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 添加到一级缓存中
this.singletonObjects.put(beanName, singletonObject);
// 从二、三级缓存中移除
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
// 按顺序添加到已注册的bean中去
this.registeredSingletons.add(beanName);
}
}
代码块4 在创建bean之前尝试走代理

创建 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

RootBeanDefinition mbdToUse = mbd;

// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
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.
// 给BeanPostProcessors一个返回代理而不是目标bean实例的机会。
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);
}

try {
// 创建bean的更具体过程,见代码块5
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
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);
}
}
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
// 在实例化之前解决
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) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 直接执行 BeanPostProcessor 初始化完成后的方法,跳过其他初始化方法(实例化之后,初始化之前)
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
// 找到所有的 BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// 判断 BeanPostProcessor 是否是 InstantiationAwareBeanPostProcessor, 只有这个接口更强大,有在bean实例化之前的钩子
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
// 如果接口返回了一个对象,那就使用这个对象,所以执行顺序很重要
if (result != null) {
return result;
}
}
}
return null;
}

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
Object result = existingBean;
// 执行每个 BeanPostProcessor 的 postProcessAfterInitialization 接口
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
// 如果有一个为 null, 那就直接返回
if (current == null) {
return result;
}
result = current;
}
return result;
}
代码块5 创建bean的实际过程

主要三个步骤:

  1. 实例化
  2. 填充属性
  3. 初始化 (Aop等)
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
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 实例化 bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

// Allow post-processors to modify the merged bean definition.
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;
}
}

// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 立刻缓存单例bean,但有三个条件,单例、允许循环引用、该bean正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 添加到三级缓存,见代码块6
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充属性,主要就是处理 @Autowired,这边展开来会很多,放在下次
populateBean(beanName, mbd, instanceWrapper);
// 初始化 bean,如果需要aop代理,会在此时进行,见代码块7
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) {
// 这部分是很重要的代码
// 这里去缓存里拿自己,为什么要这样做呢,因为缓存中可能是自己的代理对象,要用代理对象替换掉原始对象返回。但上面不是已经被初始化了,已经是代理对象了吗,其实不一定。
// 情况1: A 类是在初始化自己,如果 A 需要被代理,那么上面初始化的时候 exposedObject 的确会变成自己的代理对象。
// 情况2: 在为 A 注入 B 属性的时候,B 依赖 A ,在三级缓存中找到了 A 的工厂,执行工厂方法生成了 A 的代理对象并注入进 B,最后返回 A 执行 A 的初始化,尝试代理的时候发现已经被代理过了,所以就不需要走代理了,exposedObject == bean, 都是原始对象。
// 拿到的可能为自己的代理对象,也可能为自己本身。注意第二个参数为 false 了,不再从第三级缓存拿取。如果前两级缓存没有,那一定在第三级,而第三级缓存里的工厂只能被别的循环依赖的 bean 执行,因此,如果 earlySingletonReference 为空,说明没有发生循环依赖。
Object earlySingletonReference = getSingleton(beanName, false);
// 如果是情况1,此时不管 A 是否需要被代理, earlySingletonReference为null,表明没有发生循环依赖,所以直接返回 exposedObject,它可能是本身,如果aop了话,就是代理类。
// 如果是情况2,能取到一个值,说明发生了循环依赖。earlySingletonReference 可能是代理对象,也可能是原始对象(不需要代理)
if (earlySingletonReference != null) {
// 这个判断正常情况下一定是正确的,除非你在后置处理器中替换掉这个 bean (请不要做这种只会徒增烦恼的骚操作。)
// 为什么如果被 aop 了,也是相等的呢,exposedObject 不应该是被代理的对象了吗?解释见代码块7
if (exposedObject == bean) {
// 用自己的代理对象替换自己,如果没代理的话,它俩本就是相等的
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}

// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}

return exposedObject;
}

这就是上面说的骚操作,在正常流程中替换一个 bean,请不要这样做。

1
2
3
4
5
6
7
8
9
10
@Component
public class MyPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("a")) {
return new A();
}
return bean;
}
}
代码块6 添加到三级缓存

将bean添加到三级缓存中,添加的是该bean的ObjectFactory,一个工厂

1
2
3
4
5
6
7
8
9
10
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);
}
}
}

此方法是 ObjectFactory 的具体内容,就是找到所有的 SmartInstantiationAwareBeanPostProcessor 并执行其 getEarlyBeanReference 方法

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

其中最重要的 SmartInstantiationAwareBeanPostProcessor 是 AbstractAutoProxyCreator,用于处理代理的,其方法如下:

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
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}

// 如果需要的话,就包装这个bean
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// Create proxy if we have advice.
// 如果被切面了,就代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
代码块7 初始化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
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 调用 aware 方法
invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用初始化之前的钩子
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
// 初始化
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()) {
// 调用初始化之后的钩子
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

// 如果 bean 实现了 Aware 接口,就调用对应的方法,把值设置进去。
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

// 执行初始化之前的钩子
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

// 执行实例化之后的钩子
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

初始化 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
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {

boolean isInitializingBean = (bean instanceof InitializingBean);
// 如果 bean 实现了 InitializingBean 接口,就执行其 afterPropertiesSet 方法
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
((InitializingBean) bean).afterPropertiesSet();
}
}

// 如果在 xml 中指定了 bean 的 init-method
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 满足某些判断条件后,反射调用指定的init方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}

上面提到了 AbstractAutoProxyCreator 类的 getEarlyBeanReference 方法,里面调用了 wrapIfNecessary 方法,这个类也实现了初始化之后的钩子,用于aop代理。虽然有多个地方尝试进行包装代理,但实际上一个对象只能被代理一次,要不然会出现多个实例了,毕竟每次执行代理都产生一个新的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// remove 方法的返回值很重要,返回值就是 cacheKey 对应的值,如果不存在肯定进入逻辑,如果不为null ,说明没被 getEarlyBeanReference 处理过,只有那一个地方对 earlyProxyReferences 设置值了。
// (我认为,不会有存在这个key,但取出来的值却和 bean 不一样的情况,不知道为什么要这样写。)
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 如果需要代理的话就包装一下
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

// 把之前提到的代码粘过来作对比
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 放入 earlyProxyReferences ,用意是标记 bean 已经被early 处理过了
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}

到这里, bean 的创建过程基本就结束了。我们再用一个例子来加深理解,下图是 Chicken 和 Egg 相互循环依赖的时的创建过程, Chicken 需要被代理, Egg 无所谓是否需要代理,流程都是这样:

代理Chicken 和 Egg 循环依赖时的创建过程

为什么需要三级缓存?

如果只用二级缓存可以吗,会有什么问题呢?也是可以的,解决循环依赖有两种选择:

  1. 不管有没有依赖,实例化后都立刻创建好代理对象,并将半成品对象放入缓存,出现循环依赖时,其他对象直接取出代理对象注入即可。这种只需要二级缓存即可。
  2. 不提前创建代理对象,在出现循环引用,被其它对象注入的时,才生产代理对象。如果没有出现循环引用,就按 Spring 的设计原则走。

Spring采用的是第二种选择, Spring 的设计原则是如果没有循环依赖,通过 AnnotationAwareAspectJAutoProxyCreator 这个初始化后置处理器来在 bean 生命周期的最后一步来完成 Aop 代理,而不是实例化之后立刻进行 Aop 代理。如果出现循环依赖,要想不在实例化之后立刻 Aop 代理,只能引入第三级工厂缓存,在其他 bean 在注入自己的时候,执行 getEarlyBeanReference ,进行代理,然后注入。

但是,由于在 getBean 的时候,它也不知道有没有循环依赖,于是所有 bean 的都先将 getEarlyBeanReference 工厂添加到三级缓存中,只不过没有循环依赖的时候,完全不会用到第三级缓存罢了,有循环依赖,就执行,放入二级缓存。


参考:
面试必杀技,讲一讲Spring中的循环依赖
曹工说Spring Boot源码(29)– Spring 解决循环依赖为什么使用三级缓存,而不是二级缓存
Spring循环依赖三级缓存是否可以减少为二级缓存?