抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Spring源码分析-完成Bean实例化流程

前言

​ 在介绍了 obtainFreshBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors 三个重要方法后,我们终于来到了最后一个重要方法:finishBeanFactoryInitialization。finishBeanFactoryInitialization 是这四个方法中最复杂也是最重要的,是整个 Spring IoC 核心中的核心。

​ 该方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。

finishBeanFactoryInitialization

首先我们回到 AbstractApplicationContext.refresh() 方法,找到代码:finishBeanFactoryInitialization(beanFactory),单击该行代码跳转到具体的实现。

这个方法是spring中最重要的方法,没有之一

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
/**
* 完成bean的初始化
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//1. 初始化此上下文的转换服务
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}

//2. 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}

//3. 初始化LoadTimeWeaverAware Bean实例对象
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}

// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);

//4. 冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
beanFactory.freezeConfiguration();

//重点看这个方法,重要程度:5
//5. 实例化所有剩余(非懒加载)单例对象
beanFactory.preInstantiateSingletons();
}

preInstantiateSingletons

来到DefaultListableBeanFactory类中

这个类是处理具体实例化过程

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
/**
* 具体实例化过程
* @throws BeansException
*/
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}

// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
//xml解析时,讲过,把所有beanName都缓存到beanDefinitionNames了
//1. 创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

//2. 遍历beanNames,触发所有非懒加载单例bean的初始化
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
//3. 获取beanName对应的MergedBeanDefinitio,把父BeanDefinition里面的属性拿到子BeanDefinition中
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//4. bd对应的Bean实例:不是抽象类 && 是单例 && 不是懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//5. 判断beanName对应的bean是否为FactoryBea
if (isFactoryBean(beanName)) {
// 5.1 通过beanName获取FactoryBean实例
// 通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
//实例化的bean实现了FactoryBean
if (bean instanceof FactoryBean) {
//转换为FactoryBean
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
//5.2 判断这个FactoryBean是否希望急切的初始化
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//5.3 如果需要就马上调用getBean进行实例化 注意这里实例化的是beanName
if (isEagerInit) {
getBean(beanName);
}
}
} else {
//6. 如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例
getBean(beanName);
}
}
}
//7. 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
//7.1 拿到beanName对应的bean实例
Object singletonInstance = getSingleton(beanName);
//7.2 判断singletonInstance是否实现了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
//转换为SmartInitializingSingleton类型
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
//7.3 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

父子Bean的合并

一下内容是父子Bean合并的内容

这里先对一些概念进行解释

MergedBeanDefinition

在之后的内容你可能会频繁的见到 “MergedBeanDefinition” 这个词,因此这边先稍微讲解一下,有助于你更好的理解。

MergedBeanDefinition:这个词其实不是一个官方词,但是很接近,该词主要是用来表示 “合并的 bean 定义”,因为每次都写 “合并的 bean 定义” 有点太绕口,因此我在之后的注释或解析中或统一使用 MergedBeanDefinition 来表示 “合并的 bean 定义”。

​ 之所以称之为 “合并的”,是因为存在 “子定义” 和 “父定义” 的情况。对于一个 bean 定义来说,可能存在以下几种情况:

  • 该 BeanDefinition 存在 “父定义”:首先使用 “父定义” 的参数构建一个 RootBeanDefinition,然后再使用该BeanDefinition 的参数来进行覆盖。
  • 该 BeanDefinition 不存在 “父定义”,并且该 BeanDefinition 的类型是 RootBeanDefinition:直接返回该 RootBeanDefinition 的一个克隆。
  • 该 BeanDefinition 不存在 “父定义”,但是该 BeanDefinition 的类型不是 RootBeanDefinition:使用该 BeanDefinition 的参数构建一个 RootBeanDefinition。
  • 之所以区分出2和3,是因为通常 BeanDefinition 在之前加载到 BeanFactory 中的时候,通常是被封装成 GenericBeanDefinition 或 ScannedGenericBeanDefinition,但是从这边之后 bean 的后续流程处理都是针对 RootBeanDefinition,因此在这边会统一将 BeanDefinition 转换成 RootBeanDefinition。

​ 在我们日常使用的过程中,通常会是上面的第3种情况。如果我们使用 XML 配置来注册 bean,则该 bean 定义会被封装成:GenericBeanDefinition;如果我们使用注解的方式来注册 bean,也就是<context:component-scan /> + @Compoment,则该 bean 定义会被封装成 ScannedGenericBeanDefinition。

父 BeanFactory

​ 在 Spring 中可能存在多个 BeanFactory,多个 BeanFactory 可能存在 “父工厂” 与 “子工厂” 的关系。最常见的例子就是:Spring MVC 的 BeanFactory 和 Spring 的 BeanFactory,通常情况下,Spring 的 BeanFactory 是 “父工厂”,Spring MVC 的 BeanFactory 是 “子工厂”,在 Spring 中,子工厂可以使用父工厂的 BeanDefinition,因而,如果在当前 BeanFactory 中找不到,而又存在父工厂,则会去父工厂中查找。

父子Bean的合并的源码解读

getMergedLocalBeanDefinition

获取 beanName 对应的 MergedBeanDefinition

该类主要处理父子bean的合并类似于如下的标签将son和parent进行属性的合并

1
2
3
4
5
6
<bean id="parent" class="com.xiangxue.jack.bean.Parent" abstract="true">
<property name="username" value="parent name"/>
</bean>
<bean id="son" class="com.xiangxue.jack.bean.Son" parent="parent">
<property name="age" value="18"/>
</bean>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//该类主要处理父子bean的合并类似于如下的标签将son和parent进行属性的合并
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
//1. 检查beanName对应的MergedBeanDefinition是否存在于缓存中
//从mergedBeanDefinitions的容器中根据beanName获取RootBeanDefinition
//如果父类能够获取已经添加过的RootBeanDefinition则返回否则继续进行创建
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
//2.如果存在于缓存中则直接返回
return mbd;
}
// 3.如果不存在于缓存中
// 3.1 getBeanDefinition(beanName): 获取beanName对应的BeanDefinition,从beanDefinitionMap缓存中获取
// 3.2 getMergedBeanDefinition: 根据beanName和对应的BeanDefinition,获取MergedBeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
getMergedBeanDefinition

完成父子BeanDefinition的合并

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
/**
*完成父子BeanDefinition的合并
*/
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
//1. 加锁再进行操作
synchronized (this.mergedBeanDefinitions) {
//用于存储bd的MergedBeanDefinition,也就是该方法的结果
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;

//检查containingBd是否为空 一般是为空的
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
//2. 检查beanName对应的MergedBeanDefinition是否存在于缓存中
//从mergedBeanDefinitions容器中根据beanName获取BeanDefinition
mbd = this.mergedBeanDefinitions.get(beanName);
}
//3. 如果beanName对应的MergedBeanDefinition不存在于缓存中
if (mbd == null || mbd.stale) {
previous = mbd;
//4.如果bd的parentName为空,代表bd没有父定义,无需与父定义进行合并操作
//也就是bd的MergedBeanDefinition就是bd本身(可能需要转成RootBeanDefinition)
if (bd.getParentName() == null) {
//4.1 如果bd的类型为RootBeanDefinition,则bd的MergedBeanDefinition就是bd本身,则直接克隆一个副本
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
// 4.2 否则,将bd作为参数,构建一个RootBeanDefinition。
// 正常使用下,BeanDefinition在被加载后是GenericBeanDefinition或ScannedGenericBeanDefinition
mbd = new RootBeanDefinition(bd);
}
} else {
// 5.否则,bd存在父定义,需要与父定义合并
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
//5.1 获取父定义的beanName
String parentBeanName = transformedBeanName(bd.getParentName());
//5.2 如果父定义的beanName与该bean的beanName不同
if (!beanName.equals(parentBeanName)) {
//5.3 获取父定义的MergedBeanDefinition(因为父定义也可能有父定义,也就是bd的爷爷定义...)
pbd = getMergedBeanDefinition(parentBeanName);
} else {
//5.4 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory,
// 只有在存在父BeanFactory的情况下,才允许父定义beanName与自己相同,否则就是将自己设置为父定义
BeanFactory parent = getParentBeanFactory();
// 5.5 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
} else {
// 5.6 如果父BeanFactory不是ConfigurableBeanFactory,则抛异
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);
}
// Deep copy with overridden values.
// 5.7 使用父定义pbd构建一个新的RootBeanDefinition对象(深拷贝)
mbd = new RootBeanDefinition(pbd);
//5.8 使用bd覆盖父定义,进行父类的BeanDefinition的重写
mbd.overrideFrom(bd);
}

// 6.如果没有配置scope,则设置成默认的singleton
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}

// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
// 7.如果containingBd不为空 && containingBd不为singleton && mbd为singleton,则将mdb的scope设置为containingBd的scope
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}

//8.将beanName与mbd放到mergedBeanDefinitions缓存,以便之后可以直接使用
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
// 9.返回MergedBeanDefinition
return mbd;
}
}
transformedBeanName
1
2
3
4
5
6
7
/**
* 返回bean名称,必要时去掉工厂解引用前缀,并将别名解析为规范名称。
*
*/
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
transformedBeanName

来到BeanFactoryUtils类中

  • 如果name是以 “&” 开头的就去掉&符号返回
  • 如果不是以 “&” 开头的直接返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

/**
* 如果name是以 "&" 开头的就去掉&符号返回
* 如果不是以 "&" 开头的直接返回
*/
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
// 如果没有 "&" 前缀直接返回
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// 如果beanName带有 "&" 前缀,则去掉,并加入到transformedBeanNameCache缓存
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}

canonicalName

从aliasMap找找的bean的真正beanName

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 从aliasMap找找的bean的真正beanName
*/
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
getMergedBeanDefinition

该方法是用来获取父定义的MergedBeanDefinition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 根据name 获取BeanDefinition
*
*/
@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
// 1.获取真正的beanName(解析别名)
String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory.
// 2.如果当前BeanFactory中不存在beanName的Bean定义 && 父beanFactory是ConfigurableBeanFactory,
// 则调用父BeanFactory去获取beanName的MergedBeanDefinition
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
// 3.在当前BeanFactory中解析beanName的MergedBeanDefinition
return getMergedLocalBeanDefinition(beanName);
}

FactoryBean的实例化

FactoryBean

一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。而 FactoryBean 是一种特殊的 bean,它是个工厂 bean,可以自己创建 bean 实例,如果一个类实现了 FactoryBean 接口,则该类可以自己定义创建实例对象的方法,只需要实现它的 getObject() 方法。

很多中间件都利用 FactoryBean 来进行扩展。

扩展实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 自定义实现FactoryBean接口的bean
*/
@Component
public class CustomFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
UserDao userDao = new UserDao();
userDao.setDialect("mysql");
return userDao;
}


@Override
public Class<?> getObjectType() {
return UserDao.class;
}
}
测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SpringTest {
public static void main(String[] args) {
//创建Spring的上下文
ApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");
//获取Bean对象
System.out.println("开始调用getBean");
//获取UserDao的实例
UserDao userDao = (UserDao) context.getBean("customFactoryBean");
//获取CustomFactoryBean的实例
CustomFactoryBean customFactoryBean = (CustomFactoryBean) context.getBean("&customFactoryBean");
System.out.println(customFactoryBean);
}
}

FactoryBean实例化源码

isFactoryBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 工厂bean的解析
* 判断是beanName是否是FactoryBean
*/
@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
//1. 拿到真正的beanName(去掉&前缀、解析别名)
String beanName = transformedBeanName(name);
//2.尝试从缓存获取Bean实例对象
Object beanInstance = getSingleton(beanName, false);
// 3.beanInstance存在,则直接判断类型是否为FactoryBean
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
//4. beanDefinitionMap中不包含beanName并且bean工厂实现了ConfigurableBeanFactory就检查BeanDefinition是否是FactoryBean
// No singleton instance found -> check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
//5. 检查ParentBeanFactory是否是FactoryBean
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
//6.通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
getSingleton

从缓存中获取单例的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
/**
* 从缓存中获取单例的bean
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//1.从单例对象缓存中获取beanName对应的单例对象
//先从一级缓存拿
Object singletonObject = this.singletonObjects.get(beanName);
//2.如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
//如果bean还正在创建,还没创建完成,其实就是堆内存有了,属性还没有DI依赖注入
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 3.加锁进行操作
synchronized (this.singletonObjects) {
// 4.从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
//从二级缓存中拿
singletonObject = this.earlySingletonObjects.get(beanName);
// 5.如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用
//如果还拿不到,并且允许bean提前暴露
if (singletonObject == null && allowEarlyReference) {
// 6.从单例工厂缓存中获取beanName的单例工厂
//从三级缓存中获取
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 7.如果存在单例对象工厂,则通过工厂创建一个单例对象
//注意这是一个钩子方法
singletonObject = singletonFactory.getObject();
//升级到二级缓存
// 8.将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
//删除三级缓存
// 9.移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
// 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
this.singletonFactories.remove(beanName);
}
}
}
}
// 10.返回单例对象
return singletonObject;
}

​ 这段代码很重要,在正常情况下,该代码很普通,只是正常的检查下我们要拿的 bean 实例是否存在于缓存中,如果有就返回缓存中的 bean 实例,否则就返回 null。

​ 这段代码之所以重要,是因为该段代码是 Spring 解决循环引用的核心代码。

​ 解决循环引用逻辑:使用构造函数创建一个 “不完整” 的 bean 实例(之所以说不完整,是因为此时该 bean 实例还未初始化),并且提前曝光该 bean 实例的 ObjectFactory(提前曝光就是将 ObjectFactory 放到 singletonFactories 缓存),通过 ObjectFactory 我们可以拿到该 bean 实例的引用,如果出现循环引用,我们可以通过缓存中的 ObjectFactory 来拿到 bean 实例,从而避免出现循环引用导致的死循环。这边通过缓存中的 ObjectFactory 拿到的 bean 实例虽然拿到的是 “不完整” 的 bean 实例,但是由于是单例,所以后续初始化完成后,该 bean 实例的引用地址并不会变,所以最终我们看到的还是完整 bean 实例。

​ 这段解决逻辑涉及到了后面的一些内容,所以可能会看的不是很理解,可以先有个印象,等把创建 bean 实例都看完了,再回过头来看,可能会好理解一点。

另外这个代码块中引进了4个重要缓存:

  • singletonObjects 缓存:beanName -> 单例 bean 对象。
  • earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
  • singletonFactories 缓存:beanName -> ObjectFactory。
  • singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。
  • singletonObjects、earlySingletonObjects、singletonFactories 在这边构成了一个类似于 “三级缓存” 的概念。
isFactoryBean

检查BeanDefinition是否是FactoryBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 检查BeanDefinition是否是FactoryBean
*/
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
//1. 从mbd中拿到isFactoryBean属性
Boolean result = mbd.isFactoryBean;
if (result == null) {
// 2.拿到beanName对应的Bean实例的类型
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
// 3.返回beanType是否为FactoryBean本身、子类或子接口
result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
//5. 将结果赋值给mbd的isFactoryBean属性
mbd.isFactoryBean = result;
}
//6. 返回结果
return result;
}

总结

​ 本文执行了创建 bean 实例前的一些准备操作。主要是引入了 FactoryBean 这一特殊的 bean,获取 BeanDefinition 的 MergedBeanDefinition,最后将 BeanDefinition 统一转换成 RootBeanDefinition。

​ 另外,本文还引入了几个重要的缓存,如下:

  • mergedBeanDefinitions 缓存:beanName -> 合并的 bean 定义。
  • beanDefinitionMap 缓存:beanName -> BeanDefinition。
  • singletonObjects 缓存:beanName -> 单例 bean 对象。
  • earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
  • singletonFactories 缓存:beanName -> ObjectFactory。
  • singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。
    Spring 中大量使用了本地缓存,基本上通过名字和注释就能理解缓存的作用了。在下一篇文章中,我们将正式进入 bean 实例的获取。

Spring 中大量使用了本地缓存,基本上通过名字和注释就能理解缓存的作用了。在下一篇文章中,我们将正式进入 bean 实例的获取。

评论