在 Spring 框架中,三级缓存(Three-level Cache)机制是解决 循环依赖(Circular Dependencies) 的核心设计。Spring 通过三个 Map 容器来管理 Bean 的创建过程,从而实现对单例 Bean 的循环依赖支持。
🧠 一、什么是循环依赖?
循环依赖是指两个或多个 Bean 相互依赖对方,例如:
@Component
class A {
@Autowired
private B b;
}
@Component
class B {
@Autowired
private A a;
}
这种情况下,A 依赖 B,B 又依赖 A。如果没有特殊处理,Spring 在初始化过程中会陷入无限递归,导致启动失败。
🔁 二、Spring 如何解决循环依赖?
Spring 并不能解决所有类型的循环依赖,只能解决 单例作用域下的构造函数注入之外的循环依赖:
- ✅ 支持:字段注入、setter 注入
- ❌ 不支持:构造器注入
Spring 解决循环依赖的核心就是 三级缓存机制。
🗃️ 三、三级缓存
Spring 使用三个 Map
来实现三级缓存:
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
缓存级别 | 名称 | 类型 | 存储内容 |
---|---|---|---|
一级缓存 | singletonObjects | Map<String, Object> | 成品 Bean,已经完全初始化完成的单例 Bean |
二级缓存 | earlySingletonObjects | Map<String, Object> | 提前暴露的“早期 Bean”,尚未完成属性填充和初始化 |
三级缓存 | singletonFactories | Map<String, ObjectFactory<?>> | 存放对象工厂,用于生成“早期 Bean”,例如 AOP 代理 |
这三个缓存定义在 DefaultSingletonBeanRegistry
类中,是 AbstractBeanFactory
的父类。
🧱 四、源码
1. 调用入口:AbstractBeanFactory#getBean()
,核心方法getSingleton(beanName)
和createBean(beanName, mbd, args)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
/**
* 获取指定名称的 Bean 实例,该实例可以是单例、原型或其他作用域的。
*
* <p>这是 Spring 中获取 Bean 的核心方法之一,负责处理单例缓存、父子工厂查找、循环依赖、作用域控制等复杂逻辑。
*
* @param name 要获取的 Bean 名称(可能包含 & 前缀表示 FactoryBean)
* @param requiredType 期望的 Bean 类型,用于类型检查
* @param args 创建 Bean 时使用的参数(仅在显式调用构造函数或工厂方法时使用)
* @param typeCheckOnly 是否仅为类型检查获取 Bean(非实际使用)
* @return Bean 实例
* @throws BeansException 如果创建失败
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 将名称转换为规范的 beanName(去除 & 符号、解析别名等)
String beanName = transformedBeanName(name);
Object beanInstance;
// 首先尝试从单例缓存中快速获取 Bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
// 循环引用的情况下返回早期引用
logger.trace("返回尚未完全初始化的单例 Bean '" + beanName +
"',这可能是由于循环引用导致的");
}
else {
logger.trace("返回单例 Bean '" + beanName + "' 的缓存实例");
}
}
// 如果是 FactoryBean,则根据是否需要解引用决定是否调用 getObject()
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 如果当前正在创建原型 Bean 并且再次请求自己,抛出循环依赖异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 如果当前工厂中没有定义该 BeanDefinition,则委托给父工厂查找
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory abf) {
return abf.doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 标记该 Bean 已经开始创建(防止重复创建、支持销毁清理等)
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
// 启动性能监控步骤(可选)
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
// 获取合并后的 BeanDefinition(考虑了父子继承、默认值等)
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 确保该 Bean 所依赖的其他 Bean 已初始化(depends-on)
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(...); // 检测到循环依赖
}
registerDependentBean(dep, beanName); // 注册依赖关系
getBean(dep); // 触发依赖 Bean 的创建/获取
}
}
// 根据作用域创建 Bean
if (mbd.isSingleton()) {
// 单例模式:使用 getSingleton() 方法确保只创建一次
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args); // 创建 Bean
}
catch (BeansException ex) {
// 出现异常时清除缓存
destroySingleton(beanName);
throw ex;
}
});
// 处理 FactoryBean 场景
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// 原型模式:每次调用都创建新实例
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName); // 标记当前正在创建
prototypeInstance = createBean(beanName, mbd, args); // 创建 Bean
}
finally {
afterPrototypeCreation(beanName); // 清除标记
}
// 处理 FactoryBean 或普通 Bean
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 自定义作用域(如 request、session 等)
String scopeName = mbd.getScope();
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("未注册的作用域: " + scopeName);
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
// 处理 FactoryBean 或普通 Bean
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
if (!isCacheBeanMetadata()) {
clearMergedBeanDefinition(beanName);
}
}
}
// 类型转换适配器,确保最终返回的对象符合 requiredType
return adaptBeanInstance(name, beanInstance, requiredType);
}
2. 单例对象缓存查找:DefaultSingletonBeanRegistry#getSingleton(String beanName)
方法
public @Nullable Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
/**
* 返回在给定名称下注册的(原始)单例对象。
* <p>该方法会检查已经实例化的单例对象,并且允许获取正在创建的单例对象的早期引用,
* 从而解决循环依赖问题。
*
* @param beanName 要查找的 Bean 名称
* @param allowEarlyReference 是否允许提前暴露未完全初始化的对象(用于解决循环依赖)
* @return 注册的单例对象,如果没有找到则返回 null
*/
protected @Nullable Object getSingleton(String beanName, boolean allowEarlyReference) {
// 快速检查一级缓存(singletonObjects)是否有已创建好的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 如果一级缓存中没有,并且当前 Bean 正处于创建过程中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 查看二级缓存(earlySingletonObjects)是否存在早期暴露的对象
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果二级缓存也没有,并且允许获取早期引用
if (singletonObject == null && allowEarlyReference) {
// 尝试获取锁,防止并发创建多个相同 Bean 实例
if (!this.singletonLock.tryLock()) {
// 如果无法获取锁,则避免在此线程中推断早期单例对象,直接返回 null
return null;
}
try {
// 再次确认一级缓存是否有实例(可能其他线程刚放入)
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 确认二级缓存是否被更新
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 查找三级缓存(singletonFactories)中是否有对应的工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 使用工厂创建一个早期引用(可能是代理对象)
singletonObject = singletonFactory.getObject();
// 工厂使用后从三级缓存移除,并加入二级缓存
if (this.singletonFactories.remove(beanName) != null) {
this.earlySingletonObjects.put(beanName, singletonObject);
} else {
// 如果移除失败,说明已被其他线程处理,重新从一级缓存取值
singletonObject = this.singletonObjects.get(beanName);
}
}
}
}
}
finally {
// 释放锁
this.singletonLock.unlock();
}
}
}
return singletonObject;
}
3. 获取或创建指定名称的单例对象:DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)
方法
/**
* 获取或创建指定名称的单例对象。
* 如果该单例尚未注册,则使用提供的工厂对象来创建并注册它。
*
* @param beanName 要获取或创建的 Bean 的名称
* @param singletonFactory 用于创建单例对象的工厂(延迟调用)
* @return 注册的单例对象
*/
@SuppressWarnings("NullAway")
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean 名称不能为空");
Thread currentThread = Thread.currentThread();
Boolean lockFlag = isCurrentThreadAllowedToHoldSingletonLock();
boolean acquireLock = !Boolean.FALSE.equals(lockFlag);
boolean locked = (acquireLock && this.singletonLock.tryLock());
try {
// 先尝试从一级缓存中获取已存在的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (acquireLock && !locked) {
if (Boolean.TRUE.equals(lockFlag)) {
// 当前线程允许宽松创建,但无法获取锁时进入宽松模式
this.lenientCreationLock.lock();
try {
if (logger.isInfoEnabled()) {
Set<String> lockedBeans = new HashSet<>(this.singletonsCurrentlyInCreation);
lockedBeans.removeAll(this.singletonsInLenientCreation);
logger.info("线程 [" + currentThread.getName() +
"] 正在获取单例 Bean '" + beanName +
"',而其他线程持有单例锁:" + lockedBeans);
}
this.singletonsInLenientCreation.add(beanName); // 标记为宽松创建中
} finally {
this.lenientCreationLock.unlock();
}
} else {
// 没有锁权限,等待获取锁
this.singletonLock.lock();
locked = true;
// 再次检查是否已经有单例被创建
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject != null) {
return singletonObject;
}
}
}
// 容器正在销毁中,禁止创建新单例
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"容器正在销毁单例,不允许再创建 Bean");
}
if (logger.isDebugEnabled()) {
logger.debug("正在创建单例 Bean '" + beanName + "'");
}
try {
// 回调:标记该 Bean 正在创建中(防止循环依赖)
beforeSingletonCreation(beanName);
} catch (BeanCurrentlyInCreationException ex) {
// 处理并发创建时的异常情况
this.lenientCreationLock.lock();
try {
while ((singletonObject = this.singletonObjects.get(beanName)) == null) {
Thread otherThread = this.currentCreationThreads.get(beanName);
if (otherThread != null &&
(otherThread == currentThread ||
checkDependentWaitingThreads(otherThread, currentThread))) {
throw ex;
}
if (!this.singletonsInLenientCreation.contains(beanName)) {
break;
}
if (otherThread != null) {
this.lenientWaitingThreads.put(currentThread, otherThread);
}
try {
this.lenientCreationFinished.await(); // 等待创建完成
} catch (InterruptedException ie) {
currentThread.interrupt();
} finally {
if (otherThread != null) {
this.lenientWaitingThreads.remove(currentThread);
}
}
}
} finally {
this.lenientCreationLock.unlock();
}
if (singletonObject != null) {
return singletonObject;
}
if (locked) {
throw ex;
}
// 尝试延迟加锁以等待特定 Bean 完成
this.singletonLock.lock();
locked = true;
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject != null) {
return singletonObject;
}
beforeSingletonCreation(beanName);
}
boolean newSingleton = false;
boolean recordSuppressedExceptions = (locked && this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 再次确认是否有其他线程已经创建了该单例
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 记录当前线程正在创建此 Bean
this.currentCreationThreads.put(beanName, currentThread);
try {
// 使用工厂创建 Bean 实例
singletonObject = singletonFactory.getObject();
} finally {
this.currentCreationThreads.remove(beanName);
}
newSingleton = true;
}
} catch (IllegalStateException ex) {
// 检查是否已有单例出现(并发问题)
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;
}
// 回调:标记该 Bean 已经创建完成
afterSingletonCreation(beanName);
}
// 新建的单例需要加入缓存
if (newSingleton) {
try {
addSingleton(beanName, singletonObject);
} catch (IllegalStateException ex) {
// 如果已被其他线程抢先创建,则接受已存在的实例
Object existingObject = this.singletonObjects.get(beanName);
if (singletonObject != existingObject) {
throw ex;
}
}
}
return singletonObject;
}
} finally {
// 释放锁资源
if (locked) {
this.singletonLock.unlock();
}
this.lenientCreationLock.lock();
try {
this.singletonsInLenientCreation.remove(beanName);
this.lenientWaitingThreads.entrySet().removeIf(
entry -> entry.getValue() == currentThread);
this.lenientCreationFinished.signalAll(); // 唤醒等待线程
} finally {
this.lenientCreationLock.unlock();
}
}
}
singletonFactory.getObject()
最终调用createBean(beanName, mbd, args)
创建bean
创建bean前调用beforeSingletonCreation()
标记该 Bean 正在创建中(防止循环依赖),用来在缓存查找(getSingleton()
)判断是否出现循环依赖,添加三级缓存时也会用到
4. 创建 Bean:AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object @Nullable [] args)
方法,核心方法doCreateBean(beanName, mbdToUse, args)
/**
* 该方法是创建 Bean 实例的核心逻辑。
* 主要完成以下步骤:
* 1. 解析并加载 Bean 对应的类;
* 2. 克隆 BeanDefinition(如果有必要);
* 3. 在实例化前调用 BeanPostProcessor 获取代理对象(AOP 等机制在此介入);
* 4. 调用 doCreateBean 完成实际的 Bean 创建过程。
*
* @param beanName 要创建的 Bean 的名称
* @param mbd 合并后的 BeanDefinition(包含完整的配置信息)
* @param args 创建 Bean 时传入的构造参数(可为 null)
* @return 返回创建好的 Bean 实例
* @throws BeanCreationException 如果在创建过程中发生异常
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 1. 确保当前 Bean 所对应的类已经被正确解析
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 如果 BeanClass 是动态解析的(例如通过 ClassLoader 加载),则克隆一个新的 RootBeanDefinition
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
try {
// 准备方法覆盖(如 lookup-method 和 replaced-method)
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(
mbdToUse.getResourceDescription(), beanName,
"Validation of method overrides failed", ex);
}
}
try {
// 2. 在实例化之前,允许 BeanPostProcessor 修改或返回代理对象
// 这一步是 AOP、@Autowired 等功能的重要入口
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 {
// 3. 真正执行 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) {
// 捕获所有其他未处理的异常,并包装成 BeanCreationException 抛出
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName,
"Unexpected exception during bean creation", ex);
}
}
5.实际创建指定的 Bean: AbstractAutowireCapableBeanFactory#doCreateBean(beanName, mbdToUse, args)
方法
/**
* 实际创建指定的 Bean。
* 在这个阶段,前置处理已经完成,例如检查 postProcessBeforeInstantiation 回调。
*
* <p>该方法会根据不同的配置选择不同的实例化方式:
* - 默认构造函数实例化(instantiateBean)
* - 工厂方法实例化(instantiateUsingFactoryMethod)
* - 构造函数自动装配(autowireConstructor)
*
* @param beanName 要创建的 Bean 的名称
* @param mbd 该 Bean 的合并后的定义(包含了作用域、类名、构造参数等信息)
* @param args 显式传入的构造函数或工厂方法参数,如果为 null 则使用定义中的参数
* @return 新创建的 Bean 实例
* @throws BeanCreationException 如果 Bean 创建失败
*
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 1. 实例化 Bean:获取 BeanWrapper 对象(包装了实际的 Bean 实例)
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 如果是单例,尝试从缓存中取出提前创建的 FactoryBean 实例
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 如果没有缓存,则正常创建 Bean 实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取封装的实际 Bean 实例和类型
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
// 缓存解析出的目标类型
mbd.resolvedTargetType = beanType;
}
// 2. 应用 MergedBeanDefinitionPostProcessor,允许修改合并后的 Bean 定义
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"合并后的 Bean 定义后处理失败", ex);
}
mbd.markAsPostProcessed(); // 标记已处理
}
}
// 3. 提前暴露 Bean 引用以解决循环依赖问题(三级缓存机制的一部分)
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("提前缓存 Bean '" + beanName + "' 以支持循环引用");
}
// 将当前 Bean 包装成一个工厂对象放入三级缓存 singletonFactories 中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 4. 填充属性并初始化 Bean
Object exposedObject = bean;
try {
// 属性填充(依赖注入发生在这里)
populateBean(beanName, mbd, instanceWrapper);
// 初始化 Bean(包括 Aware 接口回调、BeanPostProcessor 处理、自定义初始化方法等)
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {
throw bce;
} else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
}
}
// 5. 检查是否有早期引用,并处理代理对象的替换
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
// 使用早期引用替代当前对象(说明没有被 AOP 代理)
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 如果有依赖此 Bean 的其他 Bean,并且不允许注入原始对象,则抛出异常
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = CollectionUtils.newLinkedHashSet(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean '" + beanName + "' 被注入到 [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] 中,但最终它被包装过。这可能导致依赖项使用的不是最终版本");
}
}
}
}
// 6. 注册销毁方法(如 DisposableBean 或 destroy-method)
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "注册销毁方法失败", ex);
}
return exposedObject;
}
调用addSingletonFactory()
方法将一个工厂对象放入三级缓存 singletonFactories 中,在缓存查找(getSingleton()
)出现循环依赖的时候用到这个工厂对象
6. 获取对指定 Bean 的早期引用:AbstractAutowireCapableBeanFactory#getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean)
方法
/**
* 获取对指定 Bean 的早期引用(early reference),通常用于解决循环依赖问题。
*
* <p>在 Spring 的 Bean 生命周期中,某些 Bean 可能会在完全初始化完成之前就被提前暴露出来,
* 以便其他 Bean 在依赖注入时可以引用到它。这种机制主要用于处理循环依赖的情况。
*
* <p>该方法会调用所有已注册的 {@link SmartInstantiationAwareBeanPostProcessor} 实现类的
* {@link SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference(Object, String)} 方法,
* 允许它们对 Bean 的早期引用进行包装或代理(例如 AOP 代理)。
*
* @param beanName 该 Bean 的名称(用于错误处理和日志记录)
* @param mbd 该 Bean 的合并后的 BeanDefinition
* @param bean 当前 Bean 的原始实例(尚未完全初始化)
* @return 返回最终要暴露的 Bean 引用对象(可能是原始 Bean 或其代理对象)
*/
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 如果该 BeanDefinition 不是合成的,并且存在 InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 遍历所有 SmartInstantiationAwareBeanPostProcessor,调用 getEarlyBeanReference 方法
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
return exposedObject;
}
出现循环依赖时会调用getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean)
AOP框架提供bp.getEarlyBeanReference(exposedObject, beanName)
7. AOP在 Bean 实例化早期阶段获取其引用:AbstractAutoProxyCreator#getEarlyBeanReference(Object bean, String beanName)
方法
/**
* 在 Bean 实例化早期阶段获取其引用,用于处理循环依赖和提前暴露代理对象。
*
* <p>该方法会在 Spring 解决循环依赖时被调用,目的是在 Bean 完全初始化之前,
* 提前暴露一个“早期引用”(early reference),以便其他 Bean 可以引用到它。
* 这是 Spring AOP 和循环依赖解决机制中的关键步骤。
*
* <p>此方法会将当前 Bean 的早期引用缓存到 `earlyBeanReferences` 中,
* 然后通过wrapIfNecessary()方法决定是否需要为该 Bean 创建代理对象。
*
* @param bean 当前正在创建的 Bean 实例(尚未完全初始化)
* @param beanName 该 Bean 的名称
* @return 返回原始 Bean 或其代理对象(如果需要 AOP 代理)
*/
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
// 构建缓存键,通常为 beanName 或带 FactoryBean 前缀的 beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 将当前 bean 的早期引用缓存起来,供后续代理逻辑使用
this.earlyBeanReferences.put(cacheKey, bean);
// 判断是否需要为该 bean 创建代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
getEarlyBeanReference(Object bean, String beanName)
是出现循环依赖时提前进行创建代理,正常创建代理(没有出现循环依赖)是在postProcessAfterInitialization()
方法,所以需要用this.earlyBeanReferences
将当前 bean 的早期引用缓存起来,供postProcessAfterInitialization()
方法代理逻辑使用
8.决定是否为其创建 AOP 代理对象: AbstractAutoProxyCreator#postProcessAfterInitialization(@Nullable Object bean, String beanName)
方法
/**
* 在 Bean 初始化完成后,决定是否为其创建 AOP 代理对象。
*
* <p>该方法是 Spring 的 {@link SmartInstantiationAwareBeanPostProcessor} 接口定义的回调方法之一,
* 被 Spring 容器在 Bean 的初始化阶段(即属性注入、初始化方法调用之后)调用。
*
* <p>其主要作用是检查当前 Bean 是否需要被包装成 AOP 代理对象。如果该 Bean 已经在早期引用阶段
* 被缓存过[getEarlyBeanReference()],并且与当前传入的 Bean 不一致,说明可能已经被代理过,则再次调用 [wrapIfNecessary()]
* 来确保最终返回的是代理后的 Bean。
*
* @param bean 当前已经完成初始化的 Bean 实例
* @param beanName 当前 Bean 的名称
* @return 原始 Bean 或者其代理对象(如果满足代理条件)
*/
@Override
public @Nullable Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 构建缓存键,用于唯一标识当前 Bean
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 如果该 Bean 曾被提前放入 earlyBeanReferences 缓存中,并且当前 Bean 与缓存中的不一致,
// 说明之前可能已经创建了一个代理对象,此时需要再次判断是否需要包装
if (this.earlyBeanReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
// 如果不需要代理,直接返回原始 Bean
return bean;
}
🎯 五、为什么不能解决构造器注入的循环依赖?
因为构造器注入必须在实例化时就完成依赖注入,而这时候 Bean 还没有放入三级缓存中,无法获取“早期引用”。
比如:
@Component
class A {
public A(B b) { } // 构造器注入
}
@Component
class B {
public B(A a) { }
}
Spring 在创建 A 时,调用构造函数时就需要 B,但 B 又需要 A,而此时 A 还未放入任何缓存,因此报错。
🧪 六、总结
特性 | 描述 |
---|---|
适用范围 | 仅适用于单例作用域 Bean |
支持类型 | setter 注入、字段注入 |
不支持类型 | 构造器注入 |
核心组件 | DefaultSingletonBeanRegistry |
关键方法 | getSingleton() 、addSingletonFactory() |
缓存层级 | 一级:成品 Bean;二级:早期 Bean;三级:Bean 工厂 |
📚 七、参考源码类(Spring 5.x)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
org.springframework.beans.factory.support.AbstractBeanFactory
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory