Spring循环依赖与三级缓存源码解析

Spring 循环依赖与三级缓存源码解析

1. 循环依赖问题

循环依赖指两个或多个 Bean 相互依赖,形成闭环。例如,Bean A 依赖 Bean B,而 Bean B 又依赖 Bean A。

2. Spring 的三级缓存机制

Spring 通过三级缓存解决循环依赖问题,三级缓存分别为:

  • 一级缓存(singletonObjects):存储完全初始化好的单例 Bean。
  • 二级缓存(earlySingletonObjects):存储提前暴露的 Bean(已实例化但未完全初始化)。
  • 三级缓存(singletonFactories):存储 Bean 的 ObjectFactory,用于生成提前暴露的 Bean。
3. 为什么需要三级缓存而非两级?
  • 两级缓存的局限性

    • 如果只有一级和二级缓存,无法处理代理对象的循环依赖。代理对象需要在对象创建后生成,而两级缓存无法保证代理对象的正确注入。
  • 三级缓存的作用

    • 三级缓存通过 ObjectFactory 延迟生成代理对象,确保在需要时生成正确的代理对象,从而解决代理对象的循环依赖问题。
4. 源码解析
  • DefaultSingletonBeanRegistry 类:
    • getSingleton(String beanName, boolean allowEarlyReference) 方法负责从缓存中获取 Bean。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}
  • AbstractAutowireCapableBeanFactory 类:
    • doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) 方法负责 Bean 的创建和初始化。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // 提前暴露 Bean,解决循环依赖
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable ex) {
        // 异常处理
    }

    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
        }
    }

    return exposedObject;
}
  • addSingletonFactory 方法:
    • 将 Bean 的 ObjectFactory 放入三级缓存。
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}
5. 总结

Spring 使用三级缓存解决循环依赖问题,确保代理对象能正确生成和注入。三级缓存通过 ObjectFactory 延迟生成代理对象,避免了两级缓存的局限性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值