Spring中的循环依赖解决详解(2)

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

final String beanName = transformedBeanName(name);
        Object bean;
             
        // 方法1)从三个map中获取单例类
        Object sharedInstance = getSingleton(beanName);
        // 省略无关代码
        }
        else {
            // 如果是多例的循环引用,则直接报错
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
            // 省略若干无关代码
            try {
                // Create bean instance.
                if (mbd.isSingleton()) {
                    // 方法2) 获取单例对象
                    sharedInstance = getSingleton(beanName, () -> {
                        try { //方法3) 创建ObjectFactory中getObject方法的返回值
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
        }
        // 省略若干无关代码
        return (T) bean;
    }

该方法比较长,对于解决循环引用来说,上面标出来的3个方法起到了至关重要的作用,下面我们挨个攻克。

3.1) getSingleton(beanName)方法: 注意该方法跟方法2)是重载方法,名字一样内部逻辑却大相径庭。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);// 步骤A
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);// 步骤B
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);// 步骤C
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/7d0b95e0035822ffae9b84633c5df7d4.html