通过上面的步骤可以看出这三个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: