Spring 三级缓存与AOP

在 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);

缓存级别名称类型存储内容
一级缓存singletonObjectsMap<String, Object>成品 Bean,已经完全初始化完成的单例 Bean
二级缓存earlySingletonObjectsMap<String, Object>提前暴露的“早期 Bean”,尚未完成属性填充和初始化
三级缓存singletonFactoriesMap<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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值