Spring--循环依赖的原理(三)--原理概述

原文网址:Spring--循环依赖的原理(三)--原理概述_IT利刃出鞘的博客-CSDN博客

简介

说明

        本文介绍Spring(SpringBoot)解决循环依赖的流程。

文章系列

  1. Spring--循环依赖的原理(一)--什么是循环依赖_IT利刃出鞘的博客-CSDN博客
  2. Spring--循环依赖的原理(二)--打断点分析_IT利刃出鞘的博客-CSDN博客
  3. Spring--循环依赖的原理(三)--原理概述_IT利刃出鞘的博客-CSDN博客
  4. Spring--循环依赖的原理(四)--为什么用三级缓存,而不是二级_IT利刃出鞘的博客-CSDN博客

三级缓存流程

  1. 从一级缓存singletonObjects中获取。()
  2. 若一级缓存中获取不到,则从二级缓存earlySingletonObjects中获取
  3. 若二级缓存中获取不到,则从三级缓存singletonFactories中获取
    1. 通过beanName获得对应的ObjectFactory,若能够获取到,则:
      1. 调用ObjectFactory#getObject获得真正的bean
      2. 把此bean从三级缓存移到二级缓存。即:singletonFactories中移除,并放入earlySingletonObjects中。

DefaultSingletonBeanRegistry 里边的三级缓存对应的map,如下所示:

/** Cache of singleton objects: bean name to bean instance. */
// 缓存单例Bean。key:bean名字,value:bean实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
 
/** Cache of early singleton objects: bean name to bean instance. */
// 缓存半成品单例Bean。key:bean名字,value:bean实例(已实例化,但未注入属性和初始化)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
 
/** Cache of singleton factories: bean name to ObjectFactory. */
// 缓存单例bean的工厂。key:bean名字,value:能够生成bean的工厂
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

代码位置

从上边可以追踪到从缓存中获取bean的位置:DefaultSingletonBeanRegistry#getSingleton(String beanName, boolean allowEarlyReference)

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;
}

bean何时被加入第3级缓存?

简介

在上边“4.三级缓存”中可以看到,第三级缓存(singletonFactories)里边放入了以bean名为键,ObjectFactory为值的项。那么,是何时放入的呢?

答:在AbstractAutowireCapableBeanFactory#doCreateBean中,populateBean之前放入的,方法为:addSingletonFactory

doCreateBean //AbstractAutowireCapableBeanFactory

// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
    if (logger.isTraceEnabled()) {
        logger.trace("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
    }
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
    populateBean(beanName, mbd, instanceWrapper);
    exposedObject = initializeBean(beanName, exposedObject, mbd);
}

addSingletonFactory  //DefaultSingletonBeanRegistry

// 放入以bean名为键,ObjectFactory为值的项

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}

getEarlyBeanReference //AbstractAutowireCapableBeanFactory

// 返回 A 的引用。(虽然 A 还在创建,未完成。)

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
            }
        }
    }
    return exposedObject;
}

三级缓存流程图

流程图

总结

  • 对于不同的bean,获取某个循环依赖的对象的位置是不同的。
  • 对于第一次获取:缓存中没有,会去创建它,然后获取。
  • 对于第二次获取:第3级缓存中有,会从第3级缓存中获取,然后将其转移到第2级缓存

getSingleton(String beanName, ObjectFactory<?> singletonFactory)

代码流程:

入口

getSingleton(String beanName, ObjectFactory<?> singletonFactory) //DefaultSingletonBeanRegistry
    // DefaultSingletonBeanRegistry
    singletonObject = singletonFactory.getObject();
    addSingleton(beanName, singletonObject);

addSingleton(String beanName, Object singletonObject)   // DefaultSingletonBeanRegistry

protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        this.singletonObjects.put(beanName, singletonObject);
        this.singletonFactories.remove(beanName);
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
    }
}

猜你喜欢

转载自blog.csdn.net/feiying0canglang/article/details/125332666