上一節(jié),我們從宏觀的角度分析了下bean實例化的預處理步驟,這一節(jié),我們重點來研究獲取單例bean,之前分析過的代碼就不在做分析了
我們直接從dogetBean說起一起再看下下面的這段代碼
Object sharedInstance = getSingleton(beanName);
//當sharedInstance不為null.并且args參數(shù)為null的時候,說明就是想獲取bean,不是創(chuàng)建bean,這個時候,就會調(diào)用getObjectForBeanInstance
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
#AbstractBeanFactory
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 如果name不為空,并且name是以&開頭,說明就是工廠bean
if (BeanFactoryUtils.isFactoryDereference(name)) {
//如果此時的工廠bean是個null,直接返回
if (beanInstance instanceof NullBean) {
return beanInstance;
}
//再次判斷beanInstance是否是工廠bean,如果不是,直接拋出異常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
//走到這里,可以判斷此時的bean有可能是一個普通的bean,有可能是一個工廠bean,如果是普通bean,直接返回
//如果是工廠bean,則調(diào)用生成一個bean實例
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
//如果mdb(RootBeanDefinition)為null,直接從緩存中獲取bean實例,spring會將生成好的單例bean緩存到currentHashMap中緩存起來
//這樣,不用每次都去創(chuàng)建了
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
//走到這里,說明緩存沒有命中,也就是說當前的bean是一個FactoryBean
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
//查看此時的根據(jù)bean名稱查看beanDefinitionMap中是否存在當前bean,beanDefinitionMap前面已經(jīng)說過了,
//當spring加載完后,會將加載的bean全部放到beanDefinitionMap
if (mbd == null && containsBeanDefinition(beanName)) {
//合并BeanDefinition
mbd = getMergedLocalBeanDefinition(beanName);
}
//判斷當前bean是否是合成的,synthetic合成的意思,但是這個地方?jīng)]有具體理解這個用法到底是啥意思,后期在研究哈
boolean synthetic = (mbd != null && mbd.isSynthetic());
//從factoryBean中獲取bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
#FactoryBeanRegistrySupport
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//檢查當前bean是否是單例
if (factory.isSingleton() && containsSingleton(beanName)) {
//緩存danlibean的map加鎖
synchronized (getSingletonMutex()) {
//從緩存中獲取bean
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//證明緩存在不存在,調(diào)用doGetObjectFromFactoryBean方法獲取bean
object = doGetObjectFromFactoryBean(factory, beanName);
//這里再一次從緩存中獲取一次bean,如果獲取到了,將alreadyThere賦值給Object,源碼解釋說是解決循環(huán)引用的時候的操作
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
//是否后置處理,
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
//走到這里,證明不是單例的,調(diào)用doGetObjectFromFactoryBean方法
Object object = doGetObjectFromFactoryBean(factory, beanName);
//判斷是否需要進行后置處理
if (shouldPostProcess) {
try {
//從factoryBean發(fā)布處理對象
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
//一些系統(tǒng)安全性檢查.咱們就不看了
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//調(diào)用getObject方法返回bean對象
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
if (object == null) {
//是否是當前正在創(chuàng)建的bean,如果是,直接拋出異常
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
//將object定義為null返回
object = new NullBean();
}
return object;
}
簡單總結(jié)一下,代碼比較多,但是邏輯不復雜,
1:判斷是否是單例bean
2:從緩存在獲取bean,
3:對bean執(zhí)行后置處理
4:最后調(diào)用factory的getObject方法返回bean
好了,獲取bean就簡單分析到這里,代碼比較簡單,邏輯也不復雜,下一期,咱們再研究下創(chuàng)建單例bean的過程.Thanks!