spring 通过三级缓存来解决 Bean 的循环依赖问题,该机制的相关代码主要位于DefaultSingletonBeanRegistry
类中。下面将从该类的源码出发,重新学习三级缓存机制。
注意:三级缓存机制只能解决 setter 注入的循环依赖问题,如果是构造器注入的方式,使用反射的方式进行注入,用三级缓存也是不能解决循环依赖问题的。本文针对的也是 setter 注入造成的循环依赖问题。
一、Bean 对象初始化入口
AbstractApplicationContext
类的 refresh()
方法
AbstractApplicationContext
类的 refresh()
方法是 Spring 容器启动和刷新的核心方法,它会完成一系列重要操作,包括 Bean 定义的加载、Bean 工厂的初始化、Bean 的创建等。
对于非懒加载的单例 Bean,Spring 容器会在 AbstractApplicationContext
的 refresh()
方法执行期间,具体是在 finishBeanFactoryInitialization
步骤中,通过 beanFactory.preInstantiateSingletons()
方法对它们进行提前初始化,确保这些 Bean 在容器启动时就已经创建并初始化完成。
注意到,在进行单例的提前初始化之前,调用了this.registerBeanPostProcessors(beanFactory)
来进行类后处理器的注册。比如说负责处理 AOP 动态增强的类后处理器 AnnotationAwareAspectJAutoProxyCreator
就是在这里注册的,确保了未来进行单例初始化时得到的是增强后的单例。
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册类后处理器
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
// 实例化所有剩余的(非懒加载的单例)Bean
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}
this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
this.resetCommonCaches();
contextRefresh.end();
}
}
}
// 先注册类后处理器
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
// 提前初始化单例(without @LazyInit)
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
......
// 提前初始化单例
beanFactory.preInstantiateSingletons();
}
二、提前初始化单例
在上部分中提到的 beanFactory.preInstantiateSingletons()
方法是接口 ConfigurableListableBeanFactory
接口提供的,其具体实现在 DefaultListableBeanFactory
类里。
在 Spring 框架中,
DefaultListableBeanFactory
是该接口的一个重要实现类。DefaultListableBeanFactory
功能强大,它综合了ListableBeanFactory
、AutowireCapableBeanFactory
、ConfigurableBeanFactory
等多个接口的能力,是 Spring 容器中完成 Bean 管理工作的核心类之一。
其提供的 preInstantiateSingletons()
方法核心功能是遍历 beanDefinitionNames,依次进行实例化。
源码分析 beanFactory.preInstantiateSingletons()
1 使用迭代器 var2 遍历 beanNames 列表。
2 对于每个 BeanName,获取其合并后的 BeanDefinition bd
。
3 通过多层 do-while
循环筛选出非抽象、单例且非懒加载的 Bean。调用getBean()
进行实例化。
- 如果是
FactoryBean
类型的 Bean,通过在 Bean 名称前加&
符号调用getBean()
方法获取FactoryBean
实例本身。 - 如果不是
FactoryBean
,直接调用getBean()
方法进行实例化。
这里这个多层的 do-while 循环的过滤模式值得学习一下
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
// 1 使用迭代器 var2 遍历 beanNames 列表
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
// 跳过抽象的bd
do {
// 过滤原型
do {
// 过滤懒加载
do {
if (!var2.hasNext()) {
// 这里是所有的 bean 都处理完(迭代器空),进入后续的 SmartInitializingSingleton 处理阶段
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
// ⚠️ 调用 DefaultSingletonBeanRegistry 的 getSingleton() 在这里面进行三级缓存!!!
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
// 是抽象的跳过
} while(bd.isAbstract());
// 不是单例的跳过
} while(!bd.isSingleton());
// 懒加载的跳过
} while(bd.isLazyInit());
// 筛选出 非抽象的、非懒加载的单例 Bean
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
// 跳出 while(true)
break;
}
// 如果是非工厂调用 getBean(beanName) 进行实例化
this.getBean(beanName);
}// true while
} while(!(bean instanceof FactoryBean));
// 直到找到的 Bean 是 FactoryBean 类型
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
@Nullable
public Object getSingleton(String beanName) {
// allowEarlyReference:true 可能返回二级缓存中的,来解决循化依赖
return this.getSingleton(beanName, true);
}
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
其中涉及到的两个核心方法:AbstractBeanFactory
的 doGetBean()
和 接口 SingletonBeanRegistry
提供的的 getSingleton()
。
其中doGetBean()
是 Spring Bean 工厂中创建和获取 Bean 实例的核心方法,当 doGetBean()
处理单例 Bean 时,会先调用 getSingleton()
检查缓存。若 Bean 不存在,doGetBean()
会通过 createBean()
实例化 Bean,并在创建过程中再次调用 getSingleton()
注册单例。
也就是说,二者的关系是:
doGetBean()
负责 Bean 的整体生命周期(实例化、依赖注入、初始化)。getSingleton()
专注于单例 Bean 的缓存和线程安全创建,是doGetBean()
在处理单例时的底层支撑。
三、AbstractBeanFactory.doGetBean()
下面提炼出一些相关的核心代码如下:
在阅读这部分源码时,注意下面几点:
- 在代码 2 部分中,是对 depends-on 强依赖关系进行的初始化,它要求在创建当前 Bean 之前,必须先创建其依赖的 Bean。这种依赖如果发生循环依赖会直接抛异常!
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = this.transformedBeanName(name);
// 1 调用 getSingleton() ,尝试在三级缓存中获取 见 三.A 部分
Object sharedInstance = this.getSingleton(beanName, true);
Object beanInstance;
if (sharedInstance != null && args == null) {
......
// 1.1 若从缓存中获取到 Bean 实例,进行一些处理返回
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
// 1.2 若没有从缓存中获取到,准备创建新的 Bean 实例
// 2.1 获取并验证 Bean 的元数据
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
// 2.2 获取强依赖 Bean 的元数据,这里是 depends-on 关系的强依赖,如果发生循环依赖是解决不了的!!!
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
// 2.2.1 如果发现循环依赖,抛出异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 2.2.2 在依赖关系 map 中注册该依赖关系
registerDependentBean(dep, beanName);
try {
// 2.2.3 这里是调用依赖 Bean 的 getBean,注意现在在走的这个方法就是目标 Bean 的 getBean,所以这里会对依赖 Bean 进行构造!
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 2.3 强依赖的 Bean 单例构造完成
// 3 目标 Bean 单例生命周期开走!
if (mbd.isSingleton()) {
// 调用 getSingleton(beanName, beanFactory);
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
} else {
......
}
}
......
return (T) beanInstance;
}
注意,在 AbstractBeanFactory
处理单例 Bean
时,会调用其父类 DefaultSingletonBeanRegistry
提供的 getSingleton(beanName, singletonFactory)
,其参数 singletonFactory 会调用抽象方法 createBean()
得到 Bean 对象,这个抽象方法的具体实现类在其子类 AbstractAutowireCapableBeanFactory
中。
A. getSingleton()
方法处理单例缓存
在 doGetBean()
方法中,会调用 DefaultSingletonBeanRegistry
类的 getSingleton()
方法来处理单例缓存。如果缓存中没有该 Bean 实例,则会调用传入的 ObjectFactory
来创建 Bean 实例。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// 1 一级缓存没有,且正处于创建中状态
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
// 2 尝试在二级缓存获取
// earlySingletonObjects 存储的是已经实例化但还未完全初始化的单例 Bean 的早期引用
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 尝试获取锁 :防止多个线程同时操作缓存,确保在多线程环境下数据的一致性
synchronized(this.singletonObjects) {
// 双重检查机制 再次检查一级二级缓存
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 3 从三级缓存(singletonFactories)中获取该 Bean 的单例工厂
// singletonFactories 存储的是创建单例 Bean 的工厂
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 4 如果三级缓存有保存,那么从单例工厂生产 Bean 的前期引用,加入二级缓存,从三级缓存中移除
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
// 5 返回单例(如果 allowEarlyReference 为 true 可能返回的是前期对象,用于避免循环依赖)
return singletonObject;
}
getSingleton(beanName, singletonFactory
的作用是如果一级缓存中存在就直接返回,否则就调用 singletonFactory 进行创建。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized(this.singletonObjects) {
// 1 尝试一级缓存获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 1 一级缓存没有,也就是没有还没有进行初始化注册
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 (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 2 将 beanName 加入到正在创建的单例名称 set singletonsCurrentlyInCreation
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
// 3 调用传入的 singletonFactory 的 getObject()创建 Bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if (recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();
while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
// 4 将新创建的 Bean 加入一级缓存
if (newSingleton) {
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
B. createBean()
方法创建 Bean 实例
在 getSingleton()
方法中调用的 ObjectFactory
会调用 AbstractAutowireCapableBeanFactory
类的 createBean()
方法来创建 Bean 实例。
值得注意的是,会在 Bean 单例实例化之前给一个调用类后处理器的机会,比如 AOP 增强就在这里插入,使得 singletonFactory 得到的可能是一个代理对象。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 解析 Bean 类
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 准备方法覆盖
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 给 BeanPostProcessor 一个机会来返回一个代理而不是目标 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 实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
C. doCreateBean()
方法完成 Bean 初始化
createBean()
方法会调用 doCreateBean()
方法,该方法会完成 Bean 的实例化、属性注入和初始化操作。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 1. 反射 实例化 Bean
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
Object bean = instanceWrapper.getWrappedInstance();
// 2. 允许提前暴露单例 Bean 以解决循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 3. 先添加 singletonFactory 到三级缓存当中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 4. 填充 Bean 属性
populateBean(beanName, mbd, instanceWrapper);
// 5. 初始化 Bean
Object exposedObject = initializeBean(beanName, bean, mbd);
return exposedObject;
}
附1:接口 SingletonBeanRegistry
DefaultSingletonBeanRegistry
是 Spring 核心接口 SingletonBeanRegistry
的具体实现类。SingletonBeanRegistry
接口为 Spring 容器提供了管理单例 Bean 的基本能力,它使得 Spring 能够集中管理单例 Bean 的注册、获取和查询等操作。抽象出了下面几种 Bean 管理方法:
registerSingleton(String beanName, Object singletonObject)
:- 该方法用于向注册表中注册一个新的单例 Bean。
beanName
是要注册的 Bean 的名称,singletonObject
是单例 Bean 的实例。如果指定的beanName
已经存在于注册表中,会抛出IllegalStateException
异常。
- 该方法用于向注册表中注册一个新的单例 Bean。
getSingleton(String beanName)
:- 根据
beanName
从注册表中获取单例 Bean 的实例。如果指定名称的单例 Bean 存在,则返回其实例;否则返回null
。
- 根据
containsSingleton(String beanName)
:- 检查注册表中是否包含指定名称的单例 Bean。如果包含则返回
true
,否则返回false
。
- 检查注册表中是否包含指定名称的单例 Bean。如果包含则返回
getSingletonNames()
:- 获取注册表中所有单例 Bean 的名称,并以数组的形式返回。
getSingletonCount()
:- 获取注册表中当前单例 Bean 的数量。
getSingletonMutex()
:- 获取用于同步单例访问的对象,通常用于确保在多线程环境下对单例 Bean 的安全访问。
附2 : 具体实现 DefaultSingletonBeanRegistry
DefaultSingletonBeanRegistry 作为 SingletonBeanRegistry 接口的实现,负责了容器中单例 Bean 的生命周期,具体而言,它提供了以下功能:
- 存储单例 Bean
- 提供单例 Bean 的注册功能
- 负责单例 Bean 的销毁
- 提供获取单例 Bean 的功能
核心字段
类型一 单例 Bean 的状态储存
Bean 单例名称储存(按注册顺序)
用一个 LinkedHashSet
类型来保存所有已经注册的单例 Bean 的名称,该数据结构决定了能够保证 Bean 的注册顺序。(LinkedHashSet
类似于 LRU 缓存,HashMap + 双向链表)。
private final Set<String> registeredSingletons = new LinkedHashSet(256);
// 保存注册了销毁的 Bean 单例
private final Map<String, Object> disposableBeans = new LinkedHashMap();
Bean 单例之间关系的储存
用三个 set 分别保存 Bean 单例之间的包含、依赖以及被依赖关系,这些关系在以后进行 Bean 的销毁时意义重大!
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap(16);
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap(64);
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap(64);
类型二 注册 Bean 单例相关
而实际注册好的 Bean 单例保存在 singletonObjects
,这是一个 ConcurrentHashMap
,键为 Bean 的名称,值为对应的 Bean 实例。同时这也是三级缓存的最高级缓存!
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
为了一定程度上解决循环依赖问题,spring 采用了三级缓存的机制,每一级缓存实际上都是一个 Map 结构,如下:
// 二级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
// 三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
singletonFactories
:- 这是一个
HashMap
,属于三级缓存,用于存储创建单例 Bean 的工厂。键为 Bean 的名称,值为ObjectFactory
实例,借助该工厂能够获取早期的单例 Bean。
- 这是一个
earlySingletonObjects
:- 这是一个
ConcurrentHashMap
,属于二级缓存,用于存储已经实例化但还未完全初始化的单例 Bean。键为 Bean 的名称,值为对应的 Bean 实例。
- 这是一个
关于具体的三级缓存机制代码将在下部分详细讲解。
类型三 Bean 单例创建状态相关
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));
private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap(16));
这是两个 Set 结构的字段,其中 singletonsCurrentlyInCreation
用于记录当前正在处于创建状态的单例 Bean 的名称。
附3: 功能实现详解
明确了该类的数据结构后,我们从几大核心方法出发来学习 Spring 是如何实现 SingletonBeanRegistry 接口需要提供的功能的:
1 registerSingleton()
该方法用于注册单例,注意到入参是 beanName
和 singletonObject
,因此在调用 registerSingleton
的时候,bean 单例已经被创建完成了。因此删除二级、三级缓存中的对象,加入一级缓存进行管理。
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized(this.singletonObjects) {
// 避免重复注册
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
} else {
// 注册
this.addSingleton(beanName, singletonObject);
}
}
}
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);
}
}
既然 registerSingleton 注册 Bean 是在初始化完成 Bean 之后调用,那实际进行 Bean 初始化的代码在哪里呢?
实际上,DefaultSingletonBeanRegistry
类中的 getSingleton
方法用于从单例缓存中获取 Bean 实例,如果不存在则调用传入的 ObjectFactory
创建 Bean。因此创建 Bean 的代码在 getSingleton 方法中。
getSingleton()
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// 1 一级缓存没有,且正处于创建中状态
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
// 2 尝试在二级缓存获取
// earlySingletonObjects 存储的是已经实例化但还未完全初始化的单例 Bean 的早期引用
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 尝试获取锁 :防止多个线程同时操作缓存,确保在多线程环境下数据的一致性
synchronized(this.singletonObjects) {
// 双重检查机制 再次检查一级二级缓存
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 3 从三级缓存(singletonFactories)中获取该 Bean 的单例工厂
// singletonFactories 存储的是创建单例 Bean 的工厂
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 4 从单例工厂生产 Bean 的前期引用,加入二级缓存,从三级缓存中移除
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
// 5 返回单例(如果 allowEarlyReference 为 true 可能返回的是前期对象,用于避免循环依赖)
return singletonObject;
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized(this.singletonObjects) {
// 1 尝试一级缓存获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 1 一级缓存没有,也就是没有还没有进行初始化注册
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 (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 2 将 beanName 加入到正在创建的单例名称 set singletonsCurrentlyInCreation
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
// 3 调用传入的 singletonFactory 的 getObject()创建 Bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if (recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();
while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
// 4 将新创建的 Bean 加入一级缓存
if (newSingleton) {
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}