主要依靠下面幾個方法:
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);
}
}