主要依靠下面几个方法:
1、getSingleton从缓存中获取单例对象
(
getBean->doGetBean方法中会调用该方法。
这里简单解释了doGetBean方法的大致流程:https://blog.csdn.net/qq_36951116/article/details/100031182
)
并且第二个参数为true,表示这个bean运行早期被引用。作用通过下面的代码可以看到,就当为true时,如果bean被提前暴露在了singletonFactories中,那么就会被获取出来,然后添加到earlySingletonObjects中。
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;
}
2、addSingletonFactory添加对象工厂ObjectFactory
(添加的对象工厂都是用于获取提前暴露出来的bean的,该方法只在一个地方被调用,在doCreateBean方法中,bean刚被创建出来,还没有被注入属性、没有被后置处理器处理时,bean会被方法对象工厂中,然后再把对象工厂通过该方法添加到singletonFactories中)
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);
}
}
}
3、addSingleton添加最终版的bean到singletonObjects
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);
}
}