Spring版本
5.2.5.RELEASE
參考
源碼解析
1. BeanFactory#getBean(String name)
應(yīng)用初始化容器的時(shí)候,bean并不會(huì)馬上被加載(除非顯式指定lazyinit = false
),而是在調(diào)用getBean
的時(shí)候才會(huì)被加載沮尿,下面我們就來看看getBean
的具體實(shí)現(xiàn)
getBean
方法實(shí)際上是交由doGetBean
實(shí)現(xiàn)的:
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
查看doGetBean
方法:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 已注冊的bean會(huì)以<beanName,bean>的形式緩存在一個(gè)map
// 1穴豫、由于BeanFactory本身也是一個(gè)bean,當(dāng)請(qǐng)求是BeanFactory這個(gè)bean的時(shí)候围辙,name是帶有&符號(hào)的,而緩存map里面的beanName都是不帶&符號(hào)的
// 2、name也有可能是bean的一個(gè)別名
// transformedBeanName方法便是將以上倆種可能的name轉(zhuǎn)化為具體的beanName
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 從緩存map中獲取bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 這里面對(duì)sharedInstance做了一些處理赎败,分為以下幾種情況:
// 1、如果name是以&符號(hào)開頭(代表想要獲取的是FactoryBean)蠢甲,
// 但是sharedInstance是NullBean僵刮,或者sharedInstance根本不是一個(gè)FactoryBean,
// 那么此時(shí)返回一個(gè)NullBean鹦牛,或者拋出異常
// 2搞糕、如果sharedInstance是一個(gè)普通bean,或者name是以&開頭能岩,代表想要獲取FactoryBean本身寞宫,此時(shí)直接返回
// 3、其他情況下拉鹃,調(diào)用getObject方法獲取真正的bean實(shí)例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// BeanFactory 無法處理Prototype類型的bean的循環(huán)依賴問題
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 獲取父BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
// 父BeanFactory不為空且<beanName,beanDefinition>的map中不含有該beanName(也就是說該bean對(duì)應(yīng)的BeanDefinition還未進(jìn)行解析),那么將獲取bean實(shí)例委托給父BeanFactory
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 將可能是別名的name解析成具體的beanName辈赋,如果name以&開頭鲫忍,那么返回值也將帶有&符號(hào)
String nameToLookup = originalBeanName(name);
// 如果是AbstractBeanFactory類型,遞歸調(diào)用doGetBean方法
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
// 如果參數(shù)不為空钥屈,調(diào)用接口層次的getBean悟民,由getBean決定具體的實(shí)現(xiàn)方法
// (getBean是一個(gè)通用接口聲明,具體有多中實(shí)現(xiàn)篷就,包含但不止AbstractBeanFactory)
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
// 參數(shù)為空射亏,與參數(shù)不為空邏輯一致,只不過交由getBean的另外一個(gè)重載方法去處理
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// typeCheckOnly
// true表示doGetBean僅僅是為了做類型檢查
// false表示為了實(shí)際使用bean實(shí)例竭业,如果是實(shí)際使用bean實(shí)例智润,則有必要標(biāo)識(shí)為已創(chuàng)建,以讓緩存起到作用
if (!typeCheckOnly) {
// 將beanName加入到alreadyCreated集合中未辆,標(biāo)識(shí)為已創(chuàng)建窟绷,并且將beanDefinition的stale屬性設(shè)置為true,防止創(chuàng)建期間元數(shù)據(jù)發(fā)生變更
markBeanAsCreated(beanName);
}
try {
// 將父bean和子bean合并咐柜,可能是從緩存中獲取
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 檢查mbd是否是抽象兼蜈,若是,拋出異常
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 保證bean下的depends on已經(jīng)實(shí)例化
// 注意depends on和循環(huán)依賴的區(qū)別
// <bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
// <property name="manager" ref="manager" />
// </bean>
// 使用@Autowired的時(shí)候拙友,我們注入的是property
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 不允許循環(huán)depends on
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注冊depends on關(guān)系为狸,注冊之后其他bean創(chuàng)建的時(shí)候才能通過isDependent方法檢查循環(huán)depends on
registerDependentBean(dep, beanName);
try {
// 創(chuàng)建depend on實(shí)例
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
// 創(chuàng)建單例類型的bean實(shí)例
// getSingleton方法后面解析
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
// 在早期的創(chuàng)建過程中,可能為了解決循環(huán)引用問題遗契,導(dǎo)致beanName加入了singleton緩存中辐棒,此時(shí)需要移除該緩存
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
// 創(chuàng)建prototype類型的bean實(shí)例
Object prototypeInstance = null;
try {
// 寫入prototype類型的依賴關(guān)系,以便上述的isPrototypeCurrentlyInCreation方法做出攔截
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 創(chuàng)建完畢則可以刪除prototype類型的依賴關(guān)系
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 創(chuàng)建其他類型的bean實(shí)例
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
// 創(chuàng)建失敗的情況下刪除緩存數(shù)據(jù)
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 檢查創(chuàng)建出來的bean實(shí)例是否是要求的類型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 不是的情況下牍蜂,進(jìn)行類型裝換
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
方法很長涉瘾,總結(jié)起來主要做了以下幾點(diǎn):
- 通過
transformedBeanName
做了beanName的轉(zhuǎn)換 - 從緩存中獲取bean實(shí)例
- 緩存不為空,通過
getObjectForBeanInstance
獲取bean實(shí)例 - 緩存為空捷兰,創(chuàng)建bean
- 緩存不為空,通過
- 將獲取到的bean實(shí)例與
requiredType
做校驗(yàn)立叛,必要時(shí)進(jìn)行類型轉(zhuǎn)換
下面逐個(gè)解析
2. 轉(zhuǎn)換beanName
方法一開始傳進(jìn)來的beanName可能有以下倆種情況:
- 以&開頭的name,代表獲取FactoryBean這個(gè)bean
- 別名
而<beanName贡茅,bean>的緩存中秘蛇,beanName是不帶&符號(hào)的非別名beanName,這時(shí)候需要將beanName轉(zhuǎn)化為真正的beanName顶考,方便后面再緩存中獲取beanName對(duì)應(yīng)的bean:
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
通過別名獲取到真正的beanName:
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
對(duì)name做去除&符號(hào)的處理:
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
// 如果name不是以&開頭赁还,直接返回
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// 否則,從transformedBeanNameCache中獲取name對(duì)應(yīng)的value驹沿,如果value為空艘策,對(duì)beanName剔除&前綴,之后寫入transformedBeanNameCache
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
其中渊季,Map#computeIfAbsent定義如下:
default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
含義是如果map中的key對(duì)應(yīng)的value為空朋蔫,那么使用mappingFunction生產(chǎn)一個(gè)值罚渐,作為value,并寫入map中
3. AbstractBeanFactory#getSingleton
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 從緩存中讀取beanName對(duì)應(yīng)的bean
Object singletonObject = this.singletonObjects.get(beanName);
// 如果不存在該beanName對(duì)應(yīng)的bean驯妄,并且該bean處于創(chuàng)建之中(由于循環(huán)依賴導(dǎo)致beanName被寫入singletonsCurrentlyInCreation)荷并,那么通過早期引用來解決循環(huán)依賴問題
// 寫入singletonsCurrentlyInCreation這一步發(fā)生在AbstractBeanFactory#doGetBean#createBean#doCreateBean#populateBean#applyPropertyValues
// #resolveValueIfNecessary#resolveInnerBean#getObjectFromFactoryBean#beforeSingletonCreation
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 從早期引用中獲取bean
singletonObject = this.earlySingletonObjects.get(beanName);
// 早期引用不存在bean且允許使用早期引用
if (singletonObject == null && allowEarlyReference) {
// 獲取bean創(chuàng)建工廠
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 調(diào)用getObject方法創(chuàng)建bean
singletonObject = singletonFactory.getObject();
// 寫入早期引用,解決循環(huán)依賴問題
this.earlySingletonObjects.put(beanName, singletonObject);
// 移除工廠
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
從緩存中獲取bean青扔,這里涉及到了循環(huán)依賴的處理源织,大致就是如果碰到當(dāng)前獲取的bean處于正在創(chuàng)建中:
isSingletonCurrentlyInCreation
那么說明當(dāng)前bean已經(jīng)處于循環(huán)依賴中,那么寫入earlySingletonObjects
中微猖,那么下次進(jìn)來谈息,就可以直接返回對(duì)應(yīng)實(shí)例,從而解決早期引用問題凛剥。
舉例來說黎茎,A依賴B,B依賴A当悔,首先創(chuàng)建A,將A寫入正在創(chuàng)建的bean集合
isSingletonCurrentlyInCreation
中踢代,然后發(fā)現(xiàn)依賴B盲憎,接著去創(chuàng)建B,發(fā)現(xiàn)依賴A胳挎,這時(shí)發(fā)現(xiàn)A處于isSingletonCurrentlyInCreation
中饼疙,那么將A寫入早期引用集合earlySingletonObjects
中,然后完成創(chuàng)建B流程慕爬,接著也就完成創(chuàng)建A流程
4. AbstractBeanFactory#getObjectForBeanInstance
查看源碼之前窑眯,有個(gè)疑問,既然已經(jīng)從緩存中獲取到了實(shí)例医窿,如果還要通過
getObjectForBeanInstance
進(jìn)行處理磅甩?這是因?yàn)閺木彺嬷蝎@取到實(shí)例是最原始的實(shí)例,如果通過getObjectForBeanInstance
進(jìn)行加工得到我們想要的實(shí)例
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 如果name以&開頭
if (BeanFactoryUtils.isFactoryDereference(name)) {
// NullBean類型直接返回
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 以&開頭代表想要獲取FactoryBean實(shí)例姥卢,但得到的實(shí)例實(shí)際上不是FactoryBean實(shí)例卷要,拋出異常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 普通類型bean實(shí)例,直接返回該實(shí)例
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 如果上述均不滿足独榴,調(diào)用BeanFactory工廠getObject方法創(chuàng)建bean
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
// 從factoryBeanObjectCache緩存中獲取緩存
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
// 合并BeanDefinition
mbd = getMergedLocalBeanDefinition(beanName);
}
// synthetic字面意思是合成的僧叉,true代表非應(yīng)用本身創(chuàng)建的bean,如使用<aop:config>創(chuàng)建的自動(dòng)代理bean
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 繼續(xù)調(diào)用getObjectFromFactoryBean方法創(chuàng)建bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
可以分成三個(gè)部分查看流程:
- 首先處理name以&開頭的情況棺榔,如果是
NullBean
瓶堕,直接返回實(shí)例beanInstance
;如果對(duì)應(yīng)實(shí)例beanInstance
不是FactoryBean
類型症歇,拋出異常郎笆;否則谭梗,返回實(shí)例beanInstance
- 如果是普通bean,直接返回對(duì)應(yīng)實(shí)例
- 如果是其他情況题画,通過
getObjectFromFactoryBean
獲得bean實(shí)例
5. AbstractBeanFactory#getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 單例模式默辨,有使用緩存
// containsSingleton方法判斷了singletonObjects是否包含beanName,而singletonObjects在doGetBean中sharedInstance為空的分支中苍息,通過getSingleton方法進(jìn)行了put
// 而這一步是sharedInstance不為空的分支走進(jìn)來的缩幸,所以這時(shí)候singletonObjects應(yīng)該是已經(jīng)包含beanName了
if (factory.isSingleton() && containsSingleton(beanName)) {
// getSingletonMutex返回singletonObjects對(duì)象,單例模式在并發(fā)情況下需要保證只創(chuàng)建一個(gè)實(shí)例竞思,所以需要對(duì)singletonObjects加鎖
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// doGetObjectFromFactoryBean調(diào)用了getObject方法
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
// TODO
// 沒看懂這幾句代碼
// 貌似是上述的getObject方法調(diào)用期間表谊,只會(huì)在不存在實(shí)例的情況下才創(chuàng)建實(shí)例并保存,所以這里要再次獲取一次盖喷,保證獲取的是第一次創(chuàng)建的實(shí)例
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// 進(jìn)入這個(gè)分支意味著object是第一次創(chuàng)建的實(shí)例爆办,這時(shí)候需要通過shouldPostProcess判斷是否進(jìn)行后置處理
// PostProcess中文含義便是"后處理"
if (shouldPostProcess) {
// TODO
// 不是很懂這里判斷的含義
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
// 將beanName加入singletonsCurrentlyInCreation
beforeSingletonCreation(beanName);
try {
// 應(yīng)用后置處理方法
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
// 將beanName從singletonsCurrentlyInCreation移除
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
// 已創(chuàng)建的實(shí)例寫入緩存
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
// 原型模式,不使用緩存课梳,每次重新創(chuàng)建
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
該段代碼主要是做了一些后置處理距辆,核心在于doGetObjectFromFactoryBean
6. AbstractBeanFactory#doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
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方法創(chuàng)建實(shí)例
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);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
7. AbstractBeanFactory#getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 查閱緩存
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
// getBeanDefinition(beanName):從beanDefinitionMap獲取BeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
// <bean id="hello" class="xyz.coolblog.innerbean.Hello">
// <property name="content" value="hello"/>
// </bean>
//
// <bean id="hello-child" parent="hello">
// <property name="content" value="I`m hello-child"/>
// </bean>
// spring支持通過以上方式進(jìn)行配置繼承,子類從而可以覆蓋或者繼承父類的配置
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// stale:陳舊暮刃,該屬性用于標(biāo)示是否需要進(jìn)行重新合并
if (mbd == null || mbd.stale) {
previous = mbd;
if (bd.getParentName() == null) {
// 沒有父類
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
// 有父類跨算,進(jìn)行合并
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
// 子beanName和父beanName不同的情況下
// 遞歸調(diào)用,獲取parentBeanDefinition
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
// 子beanName和父beanName相同的情況下
// TODO 沒看懂
// 看起來也是一個(gè)遞歸調(diào)用椭懊,但是只在parent是ConfigurableBeanFactory的情況下進(jìn)行遞歸調(diào)用
// 遞歸后最終還是得回到這個(gè)方法诸蚕,并且此時(shí)并非是ConfigurableBeanFactory類型(也就是不再進(jìn)入這個(gè)分支)
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without a ConfigurableBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
// 覆蓋或者繼承父類的配置
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
// 沒配置的情況下設(shè)置默認(rèn)singleton scope
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
// 容器是非singleton并且bean是singleton的情況下,bean不可能是singleton氧猬,此時(shí)需要進(jìn)行覆蓋
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
// 開啟緩存模式的情況下進(jìn)行緩存
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
// 重新合并背犯,使用previous的配置覆蓋mbd的配置
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}
主要邏輯就是對(duì)BeanDefinition整合一下parentBeanDefinition,對(duì)于BeanDefnition盅抚,可以戳《Spring源碼解析(一)-BeanDefinition加載》
總結(jié)
畫個(gè)流程圖理清一下doGetBean的流程
本文僅講述了獲取單例bean的流程漠魏,流程圖中createBean等源碼的解析放置于下一章節(jié)《Spring源碼解析(八)-創(chuàng)建單例bean》