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) }}在獲取到bean的例項後,需要處理如factorybean和factory-method之類的方法,後續根據不同的scope獲取到bean例項後都會執行這個方法。}return (singletonobject != null_object ? singletonobject : null);
}
protected object getobjectforbeaninstance(到這一步,就會獲得乙個bean的例項,不管bean的scope是什麼,得到例項後,我們需要進行型別轉換。比如bean是乙個string,但是需要乙個integer,那麼就需要轉換了。獲取型別轉換器後執行轉換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;
}
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 的形式進...