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

通过上面的步骤可以看出这三个map的优先级。其中singletonObjects里面存放的是初始化之后的单例对象;earlySingletonObjects中存放的是一个已完成实例化未完成初始化的早期单例对象;而singletonFactories中存放的是ObjectFactory对象,此对象的getObject方法返回值即刚完成实例化还未开始初始化的单例对象。所以先后顺序是,单例对象先存在于singletonFactories中,后存在于earlySingletonObjects中,最后初始化完成后放入singletonObjects中。

当debug到此处时,以上述Teacher和Student两个循环引用的类为例,如果第一个走到这一步的是Teacher,则从此处这三个map中get到的值都是空,因为还未添加进去。这个方法主要是给循环依赖中后来过来的对象用。

3.2)getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法:

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                // 省略无关代码
                beforeSingletonCreation(beanName); // 步骤A
                boolean newSingleton = false;
                // 省略无关代码
                try {
                    singletonObject = singletonFactory.getObject();// 步骤B
                    newSingleton = true;
                }
                // 省略无关代码
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    afterSingletonCreation(beanName);// 步骤C
                }
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);// 步骤D
                }
            }
            return singletonObject;
        }
    }

获取单例对象的主要逻辑就是此方法实现的,主要分为上面四个步骤,继续挨个看:

步骤A:

1 protected void beforeSingletonCreation(String beanName) {
2        // 判断,并首次将beanName即teacher放入singletonsCurrentlyInCreation中
3        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
4            throw new BeanCurrentlyInCreationException(beanName);
5        }
6    }

步骤C:

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

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