在DefaultSingletonBeanRegistry类中,维护了三个注释以Cache of开头的Map,通过反省可以注意到,三级缓存与前两级缓存不太一样,Map中维护的值是ObjectFactory类型。

//单例缓存池 beanName - instance 一级缓存
 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);//bean的早期引用, bean name to bean instance 二级缓存
 private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);//单例工厂 beanName - ObjectFactory 三级缓存
 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
 singletonObjects:一级缓存,一个单例bean【实例化+初始化】都完成之后,将会加入一级缓存,也就是我们俗称的单例池。
 earlySingletonObjects:二级缓存,用于存放【实例化完成,还没初始化】的实例,提前暴露,用于解决循环依赖问题。
 singletonFactories:三级缓存,存放单例对象工厂ObjectFactory,与二级缓存不同的是,它可以应对产生代理对象。
 @FunctionalInterface //函数式接口
 public interface ObjectFactory {
 T getObject() throws BeansException;
 }
 还有几个比较重要的集合://bean被创建完成之后,注册
 private final Set registeredSingletons = new LinkedHashSet<>(256);//正在创建过程中的bean待的地儿,bean在开始创建的时候放入,知道创建完成将其移除
 private final Set singletonsCurrentlyInCreation =
 Collections.newSetFromMap(new ConcurrentHashMap<>(16));
 getSingleton
 AbstractBeanFactory.doGetBean中将会出现两个重载的getSingleton方法:protected T doGetBean(…){
Object sharedInstance = getSingleton(beanName);//
// // typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。表示已经创建过一次
if (!typeCheckOnly) {
	markBeanAsCreated(beanName);
}
// 这个getSingleton方法非常关键。
//1、标注a正在创建中~
//2、调用singletonObject = singletonFactory.getObject();(实际上调用的是createBean()方法)  因此这一步最为关键
//3、标注此时实例已经创建完成
//4、执行addSingleton()添加进一级缓存,
//同时移除二级和三级缓存,还有注册
sharedInstance = getSingleton(beanName, () -> { ... return createBean(beanName, mbd, args); });}
getSingleton重载一号
 protected Object getSingleton(String beanName, boolean allowEarlyReference)我们的流程进行到AbstractBeanFactory#doGetBean的时候,会执行Object sharedInstance = getSingleton(beanName);,接着会执行getSingleton(beanName,true),一路跟进去,最终会进到DefaultSingletonBeanRegistry 的getSingleton方法,这个方法十分重要,我们具体看一看:
@Nullable
 protected Object getSingleton(String beanName, boolean allowEarlyReference) {
 //先从一级缓存中获取,获取到,就直接返回
 Object singletonObject = this.singletonObjects.get(beanName
 //如果一级缓存获取不到,且这个获取的这个bean正在创建中,就从二级缓存中获取
 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
 synchronized (this.singletonObjects) {
 //从二级缓存中获取
 singletonObject = this.earlySingletonObjects.get(beanName);
 //还是获取不到,并且allowEarlyReference为true
 if (singletonObject == null && allowEarlyReference) {
 //从三级缓存中获取
 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
 if (singletonFactory != null) {
 //循环依赖第二次进入的时候,发现A 的三级缓存,于是可以获取到A 的实例,
 singletonObject = singletonFactory.getObject();
 //获取到之后将其置入二级缓存
 this.earlySingletonObjects.put(beanName, singletonObject);
 //原先的那个就从三级缓存中移除
 this.singletonFactories.remove(beanName);
 }
 }
 }
 }
 return singletonObject;
 }
 先尝试从一级缓存中获取,如果获取到,表示这个对象已经【初始化+实例化】全部完成,当然,对于循环依赖的案例来说,这一步都是获取不到的。
 如果一级缓存中获取不到,没关系,看看这个bean是不是正在创建中【已经开始实例化,但还没有初始化完全】,如果是这个情况,就尝试从二级缓存中获取。
 如果都获取不到,且allowEarlyReference为true的时候,从三级缓存中取,三级缓存中存放的是ObjectFactory。
 getSingleton重载二号
 另外一个Singleton重载的方法:public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
 synchronized (this.singletonObjects) {
 Object singletonObject = this.singletonObjects.get(beanName);
 if (singletonObject == null) {
 //将beanName放入到singletonsCurrentlyInCreation这个集合中,标志着这个单例Bean正在创建
 beforeSingletonCreation(beanName);
 boolean newSingleton = false;
 // 传入的lambda在这里会被执行,调用createBean方法创建一个Bean后返回
 singletonObject = singletonFactory.getObject();
 newSingleton = true;
 singletonObject = this.singletonObjects.get(beanName);}
        // 创建完成后将对应的beanName从singletonsCurrentlyInCreation移除
        afterSingletonCreation(beanName);
	}
	if (newSingleton) {
        //加入一级缓存
    	addSingleton(beanName, singletonObject); 
	}
}
return singletonObject;}
 addSingleton
 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);
 }
 }addSingletonFactory
 AbstractAutowireCapableBeanFactory#doCreateBean在对象实例化完成,初始化之前进行:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
 throws BeanCreationException {
// Instantiate the bean. 实例化
BeanWrapper instanceWrapper = null;
// 调用构造器或工厂方法 实例化
instanceWrapper = createBeanInstance(beanName, mbd, args);
我们通常说的bean实例,bean的原始对象,并没有进行初始化的对象 A{ b:null}
Object bean = instanceWrapper.getWrappedInstance();

//表示是否提前暴露原始对象的引用,对于单例的bean,一般来说为true, 可以通过allowCircularReferences关闭循环引用解决循环依赖问题
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName)); 
//是否允许单例提前暴露
if (earlySingletonExposure) {
    //调用这个方法,将一个ObjectFactory放进三级缓存,二级缓存会对应删除
    //getEarlyBeanReference方法:  1、如果有SmartInstantiationAwareBeanPostProcessor,调用他的getEarlyBeanReference方法,2、如果没有,则不变还是,exposedObject
    //这里也是AOP的实现之处,AbstractAutoProxyCreator implements SmartInstantiationAwareBeanPostProcessor

    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//在bean实例化后,属性注入之前,Spring将bean包装成一个工厂添加进三级缓存中
}
//此时bean已经实例化完成, 开始准备初始化
// bean为原始对象
Object exposedObject = bean;
try {
    //负责属性的装配(如依赖注入),遇到循环依赖的情况,会在内部getBean("b")->getSingleton(b)
    populateBean(beanName, mbd, instanceWrapper);
    //处理bean初始化完成后的各种回调这里有可能返回一个代理对象
    exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//如果bean允许被早期暴露,进入代码
if (earlySingletonExposure) { 
    //第二参数为false表示不会从三级缓存中在检查,最多从二级缓存中找,其实二级缓存就够了,其实之前getSingleton的时候,已经触发了A 的ObjectFactory.getObject(),A实例已经放入二级缓存中
    Object earlySingletonReference = getSingleton(beanName, false);
    if (earlySingletonReference != null) {
        //如果没有代理,进入这个分支
        if (exposedObject == bean) {
            exposedObject = earlySingletonReference; /
        }
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
 synchronized (this.singletonObjects) {
 //如果一级缓存中尚未存在
 if (!this.singletonObjects.containsKey(beanName)) {
 //添加到三级缓存中
 this.singletonFactories.put(beanName, singletonFactory);
 //从二级缓存中移除
 this.earlySingletonObjects.remove(beanName);
 //注册一下
 this.registeredSingletons.add(beanName);
 }
 }
 }


getEarlyBeanReference
前面谈到了这个方法,还没有细说:

//是否允许单例提前暴露
if (earlySingletonExposure) {
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

它实际上就是调用了后置处理器的getEarlyBeanReference,而真正实现了这个方法的后置处理器只有AbstractAutoProxyCreator,与Aop相关,也就是说,在不考虑Aop的情况下,这个方法压根就和没调用似的。这里我们也能更加明确,三级缓存出现很大程度上也是为了更好处理代理对象。

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
 Object exposedObject = bean;
 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
 for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
 //调用后值处理器的getEarlyBeanReference
 exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
 }
 }
 return exposedObject;
 }


我们可以跟进去看一看:

//AbstractAutoProxyCreator
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
	Object cacheKey = getCacheKey(bean.getClass(), beanName);
	this.earlyProxyReferences.put(cacheKey, bean);
    //如果需要的话,返回一个代理对象
	return wrapIfNecessary(bean, beanName, cacheKey);
}