引言

从单例缓存中获取的bean原始实例,通过单例模式、原型模式或者request/session/global session等获取的bean原始实例,可能并不是我们想要的bean对象,需要通过方法:getObjectForBeanInstance获取真正的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
//获取给定bean实例的对象,对于FactoryBean,要么是bean实例本身,要么是它创建的对象。
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;
}

首先各种判断校验,返回beanInstance或者抛出异常,之后从缓存中尝试获取object。

1
2
3
4
5
6
7
/** 由FactoryBeans创建的单例对象的缓存:FactoryBean名称---对象。 */
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
//获取要从给定FactoryBean公开的对象(如果以缓存形式可用)。快速检查最小同步。
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
return this.factoryBeanObjectCache.get(beanName);
}

如果缓存中没有,则beanInstance一定是FactoryBean。在这个if分支中,先组装RootBeanDefinition,再通过getObjectFromFactoryBean方法获取对象。

1、getMergedLocalBeanDefinition

返回合并的RootBeanDefinition,如果指定的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
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
    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));
}
//如果给定bean的定义是子bean定义,则通过与父bean合并,返回给定顶级bean的RootBeanDefinition。
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
//如果给定bean的定义是子bean定义,则通过与父bean合并,返回给定bean的RootBeanDefinition。
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;
}
}

代码比较长,主要就是整合父类的各种属性,最后返回RootBeanDifinition。

2、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
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;
}
}

比较重要的方法:

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
//获取要从给定FactoryBean公开的对象。
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {

Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
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.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}

最后通过factory.getObject()方法获取对象。

tencent.jpg