spring學習(四) getBean分析

2021-10-06 05:18:50 字數 3188 閱讀 4763

spring中有乙個介面beanfactory,定義了容器的主要功能,比如建立bean、獲取bean等,是用來管理例項化、定位、配置應用程式中的物件及建立這些物件間的依賴關係的。這節主要看下getbean的方法(其內部邏輯都在dogetbean中)。

protected t dogetbean(

final string name, final classrequiredtype, final object args, boolean typecheckonly)

throws bean***ception

else

}// 主要處理factorybean,返回指定方返回的例項

bean = getobjectforbeaninstance(sharedinstance, name, beanname, null);

}//快取不存在

else

// 當前的beandefinitionmap及配置檔案不包含bean,從parentbeanfactory獲取

beanfactory parentbeanfactory = getparentbeanfactory();

if (parentbeanfactory != null && !containsbeandefinition(beanname))

else

}// 如果不僅僅是型別檢查,則是建立bean,進行標記該bean已建立

if (!typecheckonly)

try

registerdependentbean(dep, beanname);

try

catch (nosuchbeandefinitionexception ex) }}

// 例項化bean

if (mbd.issingleton())

catch (bean***ception ex)

}});

bean = getobjectforbeaninstance(sharedinstance, name, beanname, mbd);

}else if (mbd.isprototype())

finally

bean = getobjectforbeaninstance(prototypeinstance, name, beanname, mbd);

}else

try

finally

}});

bean = getobjectforbeaninstance(scopedinstance, name, beanname, mbd);

}catch (illegalstateexception ex) }}

catch (bean***ception ex)

}// 處理引數型別的轉換

if (requiredtype != null && bean != null && !requiredtype.isinstance(bean))

catch (typemismatchexception ex)

throw new beannotofrequiredtypeexception(name, requiredtype, bean.getclass());}}

return (t) bean;

}

其主要流程是:

處理beanname

嘗試從快取中獲取

建立bean

從父類查詢bean

將beandefinition轉換為rootbeandefinition

處理依賴

建立具體scope的bean

引數型別的轉換

獲取beanname的時候:由於bean的name可能是&開頭的(factorybean),或者存在別名,所以需要提取bean的名稱

public static string transformedbeanname(string name) 

return beanname;

} //返回原始bean的名字,解決別名

public string canonicalname(string name)

}while (resolvedname != null);

return canonicalname;

}

protected object getsingleton(string beanname, boolean allowearlyreference) }}

}return (singletonobject != null_object ? singletonobject : null);

}

在獲取到bean的例項後,需要處理如factorybean和factory-method之類的方法,後續根據不同的scope獲取到bean例項後都會執行這個方法。

protected object getobjectforbeaninstance(

object beaninstance, string name, string beanname, rootbeandefinition mbd)

// 如果bean不是factorybean,即一般的bean直接返回,

//如果是以&開頭的,也直接返回,因為beanname以&開頭表示的是工廠例項

if (!(beaninstance instanceof factorybean) || beanfactoryutils.isfactorydereference(name))

object object = null;

if (mbd == null)

if (object == null)

boolean synthetic = (mbd != null && mbd.issynthetic());

//通過factory_bean獲取bean例項

object = getobjectfromfactorybean(factory, beanname, !synthetic);

}return object;

}

到這一步,就會獲得乙個bean的例項,不管bean的scope是什麼,得到例項後,我們需要進行型別轉換。比如bean是乙個string,但是需要乙個integer,那麼就需要轉換了。獲取型別轉換器後執行轉換

public typeconverter gettypeconverter() 

else

}

spring學習筆記四

1 引入context命名空間 需要在xml配置檔案中配置以下資訊 這個配置隱式註冊了多個對注釋進行解析處理的處理器 autowiredannotationbeanpostprocessor,commonannotationbeanpostprocessor,persistenceannotatio...

spring學習總結 四

1 啟用spring快取 在配置檔案中匯入cache 命名空間。新增配置 針對不同的快取實現配置對應的快取管理器。2 ehcache的使用,新增jar包,然後配置ehcache.xml。配置beans.xml快取區。3 類級別 使用 cacheable執行快取 cacheable value use...

Spring 學習筆記(四)

集合屬性 在spring中可以通過一組內建的xml標籤 來配置集合屬性 當然,需要指定具體標籤,對應集合型別。可以通過簡單的value 或是用ref指向對其他bean的引用,或是通過 手寫內部bean 陣列定義和list一樣,set集合也是。map 通過entry標籤。以key value 的形式進...