美文网首页
Spring是如何解决循环依赖的

Spring是如何解决循环依赖的

作者: overflowedstack | 来源:发表于2020-04-05 12:33 被阅读0次
    有两个bean,A依赖B,B依赖A,初始化时需要解决循环依赖。

    (当然,如果bean是通过构造器注入的,则无法解决循环依赖。)

    1. 创建A,检查缓存,从singletonObjects中get,没有,
    2. 设置A的创建状态,检查beforeSingletonCreation(beanName),将A放入singletonsCurrentlyInCreation
        protected void beforeSingletonCreation(String beanName) {
            if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
        }
    
    1. create A,通过反射创建A对象之后,检查earlySingletonExposure,并放进单例工厂

    2. 填充A的属性,注入依赖。填充A的属性B,调get B来找B

    3. 从singletonObjects中get B,没有

    4. 设置B的创建状态,检查beforeSingletonCreation(beanName),将B放入this.singletonsCurrentlyInCreation.add

    5. create B,通过反射创建B对象之后,检查earlySingletonExposure,并放进缓存单例工厂

    6. 填充B的属性,注入依赖。填充B的属性A,调get A来找A

    7. 从singletonObjects中get A,没有,但是!会判断isSingletonCurrentlyInCreation

    8. 从singletonsCurrentlyInCreation中判断有没有A正在被创建,如果有

    9. 会在提前暴露的单例对象池(earlySingletonObjects)中找,没有

    10. 会从singletonFactories中获取单例工厂,可以拿到

    11. 获取到未注入属性b的A对象,然后放入earlySingletonObjects中,并移除singletonFactories中a

    12. B填充属性a,因为拿到了A对象,但这时,A还是早期的bean earlySingletonObjects

    13. B初始化,然后移除创建状态,从singletonsCurrentlyInCreation中移除b,然后放入singletonObjects

        protected void afterSingletonCreation(String beanName) {
            if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
                throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
            }
        }
    
        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);
            }
        }
    
    1. A填充属性b,b已经在singletonObjects中
    2. A初始化,然后移除创建状态,从singletonsCurrentlyInCreation中移除b,然后放入singletonObjects
    有几个关键点
    其中,最关键的对象在于earlySingletonObjects。

    第一次执行到create a时(步骤3),会调用addSingletonFactory。

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

    接下来,当b resolve a,通过singletonFactory来获取a(步骤12)时,进行了如下调用:

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

    其中,singletonFactory.getObject()做了如下调用,从这里获取到了未注入b属性的a对象。

    () -> getEarlyBeanReference(beanName, mbd, bean)
    
        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;
        }
    
    几个关键的对象如下,在DefaultSingletonBeanRegistry中:
        /** Cache of singleton objects: bean name to bean instance. */
        private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    
        /** Cache of singleton factories: bean name to ObjectFactory. */
        private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    
        /** Cache of early singleton objects: bean name to bean instance. */
        private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
    
        /** Names of beans that are currently in creation. */
        private final Set<String> singletonsCurrentlyInCreation =
                Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    
    回顾整个过程,这几个对象中的内容有以下变化:

    t1: 初始化a,实例化a之后,即将resolve b之前
    t2: resolve b,实例化b之后,即将resolve a之前
    t3: 在b里,resolve a之后
    t4: b创建好,刚刚返回到初始化a处
    t5: a创建好

    属性\时刻 t1 t2 t3 t4 t5
    singletonsCurrentlyInCreation a a, b a, b a -
    singletonFactories a a, b b - -
    earlySingletonObjects - - a a -
    singletonObjects - - - b a, b

    相关文章

      网友评论

          本文标题:Spring是如何解决循环依赖的

          本文链接:https://www.haomeiwen.com/subject/uhpjphtx.html