这一段代码是尝试从单例缓存中获取最原始的实例Bean,之后再通过getObjectForBeanInstance方法,获取我们需要的bean对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 检查单例缓存中手动注册的单例。
Object sharedInstance = getSingleton(beanName);

//单例缓存中存在这个bean
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
//指定的单例bean当前是否正在创建(在整个工厂内)。
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 + "'");
}
}
//获取给定bean实例的对象,对于FactoryBean,要么是bean实例本身,要么是它创建的对象。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

主要流程:

  • 首先从单例缓存中尝试获取bean原始实例
  • 再通过上一步获取的bean原始实例来获取我们真正使用的bean对象

下面详细分析:

1. 尝试从缓存中加载单例bean:getSingleton(String beanName)

尝试获取给定名称下注册的(原始)单例对象。SingletonBeanRegistry接口中定义的方法,DefaultSingletonBeanRegistry默认实现。

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
@Override
@Nullable
public Object getSingleton(String beanName) {
//此处allowEarlyReference为true,允许创建早期引用
return getSingleton(beanName, true);
}
/** 单例对象缓存:bean名称--bean实例。 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 早期单例对象的缓存:bean名称---bean实例。 */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** 单例工厂的缓存:bean名称---ObjectFactory。 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/**
* 返回在给定名称下注册的(原始)单例对象。
* <p>检查已实例化的单例,包括对当前创建的单例的早期引用(解析循环引用)。
*
* @param beanName 要查找的bean的名称
* @param allowEarlyReference 是否应该创建早期引用
* @return 注册的单例对象,如果没有找到,则为{@code null}
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从单例对象缓存中获取单例对象
Object singletonObject = this.singletonObjects.get(beanName);
//如果没有在singletonObjects中缓存,并且单例bean当前正在创建(在整个工厂内)
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) {
//从单例工厂中获取单例对象,ObjectFactory接口中定义的方法
singletonObject = singletonFactory.getObject();
//入早期单例对象的缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//单例工厂的缓存中删除此beanName对应的单例工厂
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}

代码相对来说比较简单,主要是从几个map中获取对象:

  • singletonObjects
    存放的是单例 bean,对应关系为 bean name –> bean instance
  • earlySingletonObjects
    存放的是早期的 bean,对应关系也是 bean name –> bean instance。它与 singletonObjects 区别在于 earlySingletonObjects 中存放的 bean 不一定是完整的,从上面过程中我们可以了解,bean 在创建过程中就已经加入到 earlySingletonObjects 中了,所以当在 bean 的创建过程中就可以通过 getBean() 方法获取。这个 Map 也是解决循环依赖的关键所在。
  • singletonFactories
    存放的是 ObjectFactory,可以理解为创建单例 bean 的 factory,对应关系是 bean name –> ObjectFactory

这三个也是解决setter循环依赖的关键。

1.1. 指定的单例bean当前是否正在创建(在整个工厂内)

1
2
3
4
5
6
7
8
9
10
11
/** 当前正在创建的bean的名称。 */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* 返回指定的单例bean当前是否正在创建(在整个工厂内)。
*
* @param beanName bean的名称
*/
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}

2. 获取给定bean实例的对象

通过getObjectForBeanInstance方法,才会真正返回我们需要的Bean对象,其方法入参中RootBeanDefinition为null。

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
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

// name以“&”开头
if (BeanFactoryUtils.isFactoryDereference(name)) {
// 若beanInstance为NullBean 直接返回
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 若beanInstance 不是FactoryBean 直接抛出异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}

// 现在我们有了bean实例,它可以是一个普通bean,也可以是一个FactoryBean。
// 如果它是一个FactoryBean,我们使用它来创建一个bean实例,
// 除非调用者实际上想要一个对工厂的引用。
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}

Object object = null;
// 若BeanDefinition为null,则从缓存中加载
if (mbd == null) {
// 从FactoryBeanRegistrySupport中定义的factoryBeanObjectCache中获取,
// 这个类继承DefaultSingletonBeanRegistry
object = getCachedObjectForFactoryBean(beanName);
}
//若object为空,则beanInstance一定是FactoryBean
if (object == null) {
// 从工厂返回bean实例。
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
//如果它是单例对象并且beanDefinitionMap中有此beanName
if (mbd == null && containsBeanDefinition(beanName)) {
//返回合并的RootBeanDefinition
mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否是用户定义的而不是应用程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 获取要从给定FactoryBean公开的对象。
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}

2.1. getCachedObjectForFactoryBean(String beanName)

为FactoryBeanRegistrySupport中方法,继承自DefaultSingletonBeanRegistry。

1
2
3
4
5
6
7
8
9
10
11
12
/** 由FactoryBeans创建的单例对象的缓存:FactoryBean名称---对象。 */
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);

/**
* 获取要从给定FactoryBean公开的对象(如果以缓存形式可用)。快速检查最小同步。
* @param beanName bean的名称
* @return 从FactoryBean中得到的对象,如果没有可用的则返回null
*/
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
return this.factoryBeanObjectCache.get(beanName);
}

2.2. 返回合并的RootBeanDefinition:getMergedLocalBeanDefinition(beanName)

就是整合此类的父类的各种属性,还有子类覆盖的各种方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
   protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// 首先快速检查map,使用最小的锁定。
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
//首先根据beanName获取BeanDefinition
//获取合并好的RootBeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
/**
* 如果给定bean的定义是子bean定义,则通过与父bean合并,返回给定bean的RootBeanDefinition。
*
* @param beanName bean定义的名称
* @param bd 原始bean定义(Root/ChildBeanDefinition)
* @param containingBd 内部bean中包含的bean定义,顶级bean中包含{@code null}
* @return 给定bean的(可能合并的)RootBeanDefinition
* @throws BeanDefinitionStoreException 如果bean定义无效时抛出
*/
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {

//锁定合并好的RootBeanDefinition
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;

// 现在检查full lock,以强制执行相同的合并实例。
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}

// 如果RootBeanDefinition为null
if (mbd == null) {
//如果bean定义的父定义的名称为空
if (bd.getParentName() == null) {
// 使用给定根bean定义的副本。
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
} else {
// 子bean定义:需要与父bean合并。
BeanDefinition pbd;
try {
//标准换父类名称
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
//继续迭代父类
pbd = getMergedBeanDefinition(parentBeanName);
} else {
//获取 Parent bean factory
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
//迭代调用
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
} else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// 具有覆盖值的深度复制。
mbd = new RootBeanDefinition(pbd);
//覆盖此bean定义(假设是从父-子继承关系复制的父)中给定bean定义(假设是子)中的设置。
mbd.overrideFrom(bd);
}

// 设置默认的单例范围,如果之前没有配置。
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}

// 非单例bean中包含的bean本身不能是单例bean。
// 让我们在这里立即纠正这个错误,
// 因为这可能是外部bean的父-子合并的结果,
// 在这种情况下,原始的内部bean定义将不会继承合并的外部bean的单例状态。
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}

// 暂时缓存合并的bean定义
// (稍后,它仍可能重新合并,以获取元数据更改)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}

return mbd;
}
}


2.3. 获取要从给定FactoryBean公开的对象

getObjectFromFactoryBean(factory, beanName, !synthetic)核心方法。为FactoryBeanRegistrySupport中提供的方法,FactoryBeanRegistrySupport继承自DefaultSingletonBeanRegistry。

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
/**
* 获取要从给定FactoryBean公开的对象。
* @param factory FactoryBean实例
* @param beanName bean的名称
* @param shouldPostProcess 是否对bean进行后处理
* @return 从FactoryBean获得的对象
* @throws BeanCreationException 如果FactoryBean对象创建失败
* @see FactoryBean#getObject()
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {

//如果为单例模式并且缓存中存在beanName
if (factory.isSingleton() && containsSingleton(beanName)) {
//锁住singletonObjects
synchronized (getSingletonMutex()) {
//从缓存中获取对象
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//调用factory的getObject()方法获取对象
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// 如果在上面的getObject()调用期间还没有存储,则只存储后处理和存储
// (e.g. 因为自定义getBean调用触发了循环引用处理)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
//如果上面没用从缓存中获取到对象
else {
//是否需要后处理
if (shouldPostProcess) {
//在整个工厂范围内,这个bean正在创建单例
if (isSingletonCurrentlyInCreation(beanName)) {
// 临时返回非后处理对象,还没有存储它。
return object;
}
//创建单例前置处理
beforeSingletonCreation(beanName);
try {
//对从FactoryBean获得的给定对象进行后处理。
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
//创建单例后置
afterSingletonCreation(beanName);
}
}
//如果时单例,就缓存这个对象
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}else {
//调用factory的getObject()方法获取对象
Object object = doGetObjectFromFactoryBean(factory, beanName);
//后处理
if (shouldPostProcess) {
try {
//对从FactoryBean获得的给定对象进行后处理。
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}

参考:

【死磕 Spring】—– IOC 之从单例缓存中获取单例 bean

tencent.jpg