GetBean源碼全面解讀

GetBean源碼部分

protected??T?doGetBean(finalStringname,@NullablefinalClass?requiredType,

@NullablefinalObject[]?args,?boolean?typeCheckOnly)?throws?BeansException?{

//會(huì)包括解析別名等操作

finalStringbeanName?=?transformedBeanName(name);

Objectbean;

//?先檢查單例列表中是否已經(jīng)注冊(cè)了這個(gè)bean

ObjectsharedInstance?=?getSingleton(beanName);

if(sharedInstance?!=null&&?args?==null)?{

bean?=?getObjectForBeanInstance(sharedInstance,?name,?beanName,null);

}

else{

//?檢查bean是否并發(fā)被創(chuàng)建

if(isPrototypeCurrentlyInCreation(beanName))?{

thrownewBeanCurrentlyInCreationException(beanName);

}

//?檢查是否在父類工廠中,邏輯和這個(gè)差不多,這里省略....

//標(biāo)記bean正在被創(chuàng)建

if(!typeCheckOnly)?{

markBeanAsCreated(beanName);

}

try{

//合并父類中的方法及屬性,下面會(huì)細(xì)講??????????????????????

finalRootBeanDefinition?mbd?=?getMergedLocalBeanDefinition(beanName);

//檢查這個(gè)bean是否為抽象類

checkMergedBeanDefinition(mbd,?beanName,?args);

//?這里是為了保證獲取的bean的依賴都需要先生成

String[]?dependsOn?=?mbd.getDependsOn();

if(dependsOn?!=null)?{

for(Stringdep?:?dependsOn)?{

if(isDependent(beanName,?dep))?{

thrownewBeanCreationException(mbd.getResourceDescription(),?beanName,

"Circular?depends-on?relationship?between?'"+?beanName?+"'?and?'"+?dep?+"'");

}

registerDependentBean(dep,?beanName);

try{

getBean(dep);

}

catch(NoSuchBeanDefinitionException?ex){

throwex;

}

}

}

//?創(chuàng)建單例的bean,看下方的createBean方法

if(mbd.isSingleton())?{

sharedInstance?=?getSingleton(beanName,?()?->?{

try{

returncreateBean(beanName,?mbd,?args);

}

catch(BeansException?ex)?{

destroySingleton(beanName);

throwex;

}

});

bean?=?getObjectForBeanInstance(sharedInstance,?name,?beanName,?mbd);

}

elseif(mbd.isPrototype())?{

//?It's?a?prototype?->?create?a?new?instance.

ObjectprototypeInstance?=null;

try{

beforePrototypeCreation(beanName);

prototypeInstance?=?createBean(beanName,?mbd,?args);

}

finally{

afterPrototypeCreation(beanName);

}

bean?=?getObjectForBeanInstance(prototypeInstance,?name,?beanName,?mbd);

}

else{

StringscopeName?=?mbd.getScope();

finalScope?scope?=this.scopes.get(scopeName);

if(scope?==null)?{

thrownewIllegalStateException("No?Scope?registered?for?scope?name?'"+?scopeName?+"'");

}

try{

ObjectscopedInstance?=?scope.get(beanName,?()?->?{

beforePrototypeCreation(beanName);

try{

returncreateBean(beanName,?mbd,?args);

}

finally{

afterPrototypeCreation(beanName);

}

});

bean?=?getObjectForBeanInstance(scopedInstance,?name,?beanName,?mbd);

}

catch(IllegalStateException?ex)?{

thrownewBeanCreationException(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)?{

cleanupAfterBeanCreationFailure(beanName);

throwex;

}

}

//?檢查需要的類型和實(shí)際傳參類型是否一致.?這里省略....

return(T)?bean;

}

整個(gè)操作大概是以下幾步:

獲取實(shí)際的beanName,其中會(huì)處理帶&號(hào)前綴的beanName,并解析別名。

檢查單例列表中是否存在該beanName的bean,若存在則無需走下面的創(chuàng)建bean的流程。

若單例列表中并不存在此bean,則檢查是否有并發(fā)創(chuàng)建。這里的判斷只針對(duì)scope為prototype類型的bean。

檢查bean是否存在于父類工廠中,若存在,則走父類工廠的getBean流程。向上委托,保證容器中只會(huì)存在一個(gè)同名的bean。

標(biāo)記bean正在被創(chuàng)建。

如果有父類,這里會(huì)遞歸合并父類的方法以及屬性。并會(huì)用自己重寫的方法覆蓋其父類的方法。合并完成并檢查這個(gè)bean的是否是抽象類。

如果該bean上有注解@DependsOn,或者配置文件上配置有該屬性,則需保證該bean的所有依賴需要先在容器內(nèi)注冊(cè)。

分單例和原型以及其他scope類型來創(chuàng)建bean。

檢查需要的類型和生成的bean類型是否一致。

返回創(chuàng)建好的bean。

getSingleton源碼部分(beanName,allowEarlyReference)

這里的singletonObjects是一個(gè)緩存了beanName和bean的Map,若存在,直接返回。

不存在,則檢查是否這個(gè)bean是否正在創(chuàng)建的過程中,先檢查earlySingletonObjects這個(gè)容器,這個(gè)容器里面放著的是已經(jīng)構(gòu)造完成但是沒有注入屬性的對(duì)象,若存在,也會(huì)直接返回。

嘗試著從singletonFactories中獲取,然后調(diào)用getObject方法去獲取對(duì)象。并將獲取到的對(duì)象放到earlySingletonObjects容器中,然后從singletonFactories容器中移除。

這里這么設(shè)計(jì)是為了解決循環(huán)依賴的問題。若A依賴B,B依賴C,C又依賴A,這樣三個(gè)bean就形成了一個(gè)環(huán)(這里只是針對(duì)set方法注入的bean,構(gòu)造器注入還是會(huì)有循環(huán)依賴的問題而拋出異常的),spring會(huì)將創(chuàng)建的bean實(shí)例提前暴露在緩存中,一旦下一個(gè)bean創(chuàng)建的時(shí)候需要依賴上個(gè)bean,則直接使用ObjectFactory來獲取bean。

這里舉個(gè)生活中的例子闡述下:就拿建一個(gè)小區(qū)房來說,建房子是一個(gè)很復(fù)雜的工序,但是咱們只要把架子搭好,告訴大家這塊地是用來建這個(gè)房子的就行。至于其他裝修,家私等等東西都可以后面再進(jìn)行補(bǔ)充。咱們不能搭架子的時(shí)候去放家具吧,這樣整個(gè)都會(huì)亂套,也不符合常理。(這里房子的框架是咱們程序中的一個(gè)對(duì)象A,家具是另一個(gè)對(duì)象B,A依賴B,B依賴A)

循環(huán)依賴

相關(guān)的邏輯有用到以下代碼段:

每次singleton bean創(chuàng)造之前都會(huì)調(diào)用的方法,在singletonsCurrentlyInCreation容器中加入這個(gè)bean的beanName,標(biāo)記這個(gè)bean正在創(chuàng)建中,供后期生成ObjectFactory。這里有個(gè)inCreationCheckExclusions容器,在這里我理解為屬于該容器的bean必須要初始化完成才允許被獲取。也就是說,添加進(jìn)該容器后bean便不會(huì)允許早期的循環(huán)依賴了。

上面的代碼片段的調(diào)用在doCreateBean源碼中(排在bean對(duì)象創(chuàng)建之后和屬性注入之前),可以觀察到要執(zhí)行addSingletonFactory方法需要滿足三個(gè)條件:

這個(gè)bean是單例的,

允許循環(huán)依賴,

這個(gè)bean正在被創(chuàng)建的過程中。

在滿足這三個(gè)條件的情況下,會(huì)在singletonFactories容器中緩存一個(gè)生成該bean的工廠,將其提前暴露出去。這里關(guān)注下getEarlyBeanReference(beanName, mbd, bean)這個(gè)方法,實(shí)際上ObjectFactory中g(shù)etObject方法調(diào)用的也是這個(gè)方法。

getMergedBeanDefinition源碼部分

看這部分之前,首先得明白BeanDefinition是用來干什么的,這個(gè)類會(huì)在整個(gè)源碼解析過程中出現(xiàn)無數(shù)次。Spring把BeanDefinition定義成IOC容器的內(nèi)部數(shù)據(jù)結(jié)構(gòu),實(shí)際上它也就是POJO對(duì)象在IOC容器中的抽象,通過這個(gè)對(duì)象,IOC容器能很方便的對(duì)Bean進(jìn)行管理,包括利用它進(jìn)行屬性的注入等等…

protectedRootBeanDefinitiongetMergedBeanDefinition(

String?beanName,?BeanDefinition?bd,?@Nullable?BeanDefinition?containingBd)

throwsBeanDefinitionStoreException

{

synchronized(this.mergedBeanDefinitions)?{

RootBeanDefinition?mbd?=null;

//?重新去獲取一次,有可能該BeanDefinition已經(jīng)生成

if(containingBd?==null)?{

mbd?=this.mergedBeanDefinitions.get(beanName);

}

if(mbd?==null)?{

if(bd.getParentName()?==null)?{

//?沒有父類則深拷貝一個(gè)RootBeanDefinition

if(bdinstanceofRootBeanDefinition)?{

mbd?=?((RootBeanDefinition)?bd).cloneBeanDefinition();

}

else{

mbd?=newRootBeanDefinition(bd);

}

}

else{

//?有父類則需要先獲取父類的BeanDefinition,流程和獲取子類的BeanDefinition一致

BeanDefinition?pbd;

try{

String?parentBeanName?=?transformedBeanName(bd.getParentName());

if(!beanName.equals(parentBeanName))?{

pbd?=?getMergedBeanDefinition(parentBeanName);

}

else{

BeanFactory?parent?=?getParentBeanFactory();

if(parentinstanceofConfigurableBeanFactory)?{

pbd?=?((ConfigurableBeanFactory)?parent).getMergedBeanDefinition(parentBeanName);

}

else{

thrownewNoSuchBeanDefinitionException(parentBeanName,

"Parent?name?'"+?parentBeanName?+"'?is?equal?to?bean?name?'"+?beanName?+

"':?cannot?be?resolved?without?an?AbstractBeanFactory?parent");

}

}

}

catch(NoSuchBeanDefinitionException?ex)?{

thrownewBeanDefinitionStoreException(bd.getResourceDescription(),?beanName,

"Could?not?resolve?parent?bean?definition?'"+?bd.getParentName()?+"'",?ex);

}

//這里進(jìn)行深拷貝,并將子類重寫的方法和屬性進(jìn)行覆蓋

mbd?=newRootBeanDefinition(pbd);

mbd.overrideFrom(bd);

}

//?若前面沒配置scope類型,這里設(shè)置為單例范圍

if(!StringUtils.hasLength(mbd.getScope()))?{

mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);

}

//?這里對(duì)內(nèi)部類做了一些處理,若包含它的bean不是單例的,則該bean也將不會(huì)是單例的

if(containingBd?!=null&&?!containingBd.isSingleton()?&&?mbd.isSingleton())?{

mbd.setScope(containingBd.getScope());

}

//?將生產(chǎn)的BeanDefinition?緩存起來

if(containingBd?==null&&?isCacheBeanMetadata())?{

this.mergedBeanDefinitions.put(beanName,?mbd);

}

}

returnmbd;

}

}

在mergedBeanDefinitions同步的情況下再次讀取緩存,防止該BeanDefinition已經(jīng)被合并過了。

檢查是否有父類,若有父類,則必須遞歸去合并BeanDefinition。

將子類重寫后的方法覆蓋到定義的BeanDefinition中。

設(shè)置scope類型。

將生成的BeanDefinition緩存起來。

registerDependentBean源碼部分

這一部分應(yīng)該還是很容易理解的,這里面出現(xiàn)了兩個(gè)Map,一個(gè)是dependentBeanMap,它主要用來裝載鍵為beanName值為dependentBeanName的容器,另一個(gè)dependenciesForBeanMap是用來裝載鍵為dependentBeanName值為beanName的容器,這樣可以方便我們觀察一個(gè)類需要組裝哪些依賴,然后這個(gè)類同時(shí)是哪些類的依賴。

getSingleton源碼部分(beanName,singletonFactory)

publicObject?getSingleton(String?beanName,?ObjectFactory?singletonFactory)?{

Assert.notNull(beanName,"Bean?name?must?not?be?null");

synchronized?(this.singletonObjects)?{

//先去singletonObjects容器中去獲取,能獲取到就直接返回了

Object?singletonObject?=this.singletonObjects.get(beanName);

if(singletonObject?==null)?{

//調(diào)用destroySingletons方法singletonsCurrentlyInDestruction屬性才會(huì)變成true

if(this.singletonsCurrentlyInDestruction)?{

thrownew?Exception("xx"));

}

//這里會(huì)將beanName緩存到singletonsCurrentlyInCreation集合中

beforeSingletonCreation(beanName);

boolean?newSingleton?=false;

boolean?recordSuppressedExceptions?=?(this.suppressedExceptions?==null);

if(recordSuppressedExceptions)?{

this.suppressedExceptions?=?new?LinkedHashSet<>();

}

try{

//這里會(huì)觸發(fā)下面的createBean方法

singletonObject?=?singletonFactory.getObject();

newSingleton?=true;

}

catch(IllegalStateException?ex)?{

//?如果是與此同時(shí)被創(chuàng)建了,則直接獲取,如果能獲取到值不為null,則正常返回。

//(注意這里捕獲異常正常返回的話就不會(huì)走下面的addSingleton方法了。)

singletonObject?=this.singletonObjects.get(beanName);

if(singletonObject?==null)?{

throwex;

}

}

catch(BeanCreationException?ex)?{

if(recordSuppressedExceptions)?{

for(Exception?suppressedException?:this.suppressedExceptions)?{

ex.addRelatedCause(suppressedException);

}

}

throwex;

}

finally{

if(recordSuppressedExceptions)?{

this.suppressedExceptions?=null;

}

//這里會(huì)將beanName從singletonsCurrentlyInCreation集合中移除

afterSingletonCreation(beanName);

}

if(newSingleton)?{

//添加到singletonObjects和registeredSingletons緩存中,并從singletonFactories和earlySingletonObjects中移除

addSingleton(beanName,?singletonObject);

}

}

returnsingletonObject;

}

}

直接去singletonObjects中獲取,獲取到了便直接返回。

獲取不到,先將beanName緩存到singletonsCurrentlyInCreation集合中,作為標(biāo)記表示該bean正在被創(chuàng)建的過程中。

觸發(fā)createBean方法去創(chuàng)建bean,這里可以去看一下ObjectFactory這個(gè)接口工廠,這里是對(duì)getObject方法的一個(gè)回調(diào)(AbstractAutowireCapableBeanFactory中的createBean方法)。

創(chuàng)建bean的過程中在不出異常的情況下便會(huì)進(jìn)行下圖的操作后并返回,也就操作了幾個(gè)容器的緩存而已。

createBean源碼部分

這一塊不是很復(fù)雜,復(fù)雜的地方在doCreateBean這個(gè)方法中。

protectedObjectcreateBean(StringbeanName,?RootBeanDefinition?mbd,@NullableObject[]?args)

throws?BeanCreationException?{

RootBeanDefinition?mbdToUse?=?mbd;

//?要保證RootBeanDefinition的beanClass是存在的

Class?resolvedClass?=?resolveBeanClass(mbd,?beanName);

if(resolvedClass?!=null&&?!mbd.hasBeanClass()?&&?mbd.getBeanClassName()?!=null)?{

mbdToUse?=newRootBeanDefinition(mbd);

mbdToUse.setBeanClass(resolvedClass);

}

//?這一塊沒什么研究,注解意思是(檢查所有帶有override的方法是否都是存在的)

try{

mbdToUse.prepareMethodOverrides();

}

catch(BeanDefinitionValidationException?ex)?{

}

try{

//這一塊我猜測(cè)大概是看咱們自己有提供實(shí)例化的方法不,若有,則不會(huì)走下面的doCreateBean方法。

Objectbean?=?resolveBeforeInstantiation(beanName,?mbdToUse);

if(bean?!=null)?{

returnbean;

}

}

catch(Throwable?ex)?{

}

try{

//創(chuàng)建bean的真正方法

ObjectbeanInstance?=?doCreateBean(beanName,?mbdToUse,?args);

}

returnbeanInstance;

}

catch(Exception?e){

throwe;

}

}

doCreateBean源碼部分

protectedObjectdoCreateBean(finalStringbeanName,finalRootBeanDefinition?mbd,final@NullableObject[]?args)

throws?BeanCreationException?{

//?Instantiate?the?bean.

BeanWrapper?instanceWrapper?=null;

if(mbd.isSingleton())?{

instanceWrapper?=this.factoryBeanInstanceCache.remove(beanName);

}

if(instanceWrapper?==null)?{

//?創(chuàng)建這個(gè)bean,真正構(gòu)建時(shí)有分兩種情況,jdk反射和cglib動(dòng)態(tài)代理

instanceWrapper?=?createBeanInstance(beanName,?mbd,?args);

}

finalObjectbean?=?instanceWrapper.getWrappedInstance();

Class?beanType?=?instanceWrapper.getWrappedClass();

if(beanType?!=?NullBean.class)?{

mbd.resolvedTargetType?=?beanType;

}

//?允許后置處理器來修改這個(gè)BeanDefinition

synchronized?(mbd.postProcessingLock)?{

if(!mbd.postProcessed)?{

try{

applyMergedBeanDefinitionPostProcessors(mbd,?beanType,?beanName);

}

catch(Throwable?ex)?{

thrownewBeanCreationException(mbd.getResourceDescription(),?beanName,

"Post-processing?of?merged?bean?definition?failed",?ex);

}

mbd.postProcessed?=true;

}

}

//?用來解決循環(huán)依賴問題的,上面已經(jīng)有過詳細(xì)解釋了??瓷厦嫜h(huán)依賴模塊

boolean?earlySingletonExposure?=?(mbd.isSingleton()?&&this.allowCircularReferences?&&

isSingletonCurrentlyInCreation(beanName));

if(earlySingletonExposure)?{

if(logger.isTraceEnabled())?{

logger.trace("Eagerly?caching?bean?'"+?beanName?+

"'?to?allow?for?resolving?potential?circular?references");

}

addSingletonFactory(beanName,?()?->?getEarlyBeanReference(beanName,?mbd,?bean));

}

//?Initialize?the?bean?instance.

ObjectexposedObject?=?bean;

try{

//進(jìn)行屬性的注入,調(diào)用bean的set方法進(jìn)行字段的初始化

populateBean(beanName,?mbd,?instanceWrapper);

//進(jìn)行一些初始化方法的調(diào)用,比如afterPropertiesSet等等。

exposedObject?=?initializeBean(beanName,?exposedObject,?mbd);

}

catch(Throwable?ex)?{

if(ex?instanceof?BeanCreationException?&&?beanName.equals(((BeanCreationException)?ex).getBeanName()))?{

throw(BeanCreationException)?ex;

}

}

if(earlySingletonExposure)?{

ObjectearlySingletonReference?=?getSingleton(beanName,false);

if(earlySingletonReference?!=null)?{

if(exposedObject?==?bean)?{

exposedObject?=?earlySingletonReference;

}

//在出現(xiàn)循環(huán)依賴后,從earlySingletonObjects中獲取的bean對(duì)象和initializeBean后

//的不一致,證明被后置處理器處理過了,前后bean不一致,需要拋出異常

elseif(!this.allowRawInjectionDespiteWrapping?&&?hasDependentBean(beanName))?{

String[]?dependentBeans?=?getDependentBeans(beanName);

Set?actualDependentBeans?=newLinkedHashSet<>(dependentBeans.length);

for(StringdependentBean?:?dependentBeans)?{

if(!removeSingletonIfCreatedForTypeCheckOnly(dependentBean))?{

actualDependentBeans.add(dependentBean);

}

}

if(!actualDependentBeans.isEmpty())?{

thrownewBeanCurrentlyInCreationException(beanName,

"Bean?with?name?'"+?beanName?+"'?has?been?injected?into?other?beans?["+

StringUtils.collectionToCommaDelimitedString(actualDependentBeans)?+

"]?in?its?raw?version?as?part?of?a?circular?reference,?but?has?eventually?been?"+

"wrapped.?This?means?that?said?other?beans?do?not?use?the?final?version?of?the?"+

"bean.?This?is?often?the?result?of?over-eager?type?matching?-?consider?using?"+

"'getBeanNamesOfType'?with?the?'allowEagerInit'?flag?turned?off,?for?example.");

}

}

}

}

//?注冊(cè)bean的銷毀方法

try{

registerDisposableBeanIfNecessary(beanName,?bean,?mbd);

}

catch(BeanDefinitionValidationException?ex)?{

thrownewBeanCreationException(

mbd.getResourceDescription(),?beanName,"Invalid?destruction?signature",?ex);

}

returnexposedObject;

}

doCreateBean大概有以下步驟:

調(diào)用createBeanInstance方法初始化bean實(shí)例,這里不包括屬性的注入。

調(diào)用合并bean的后置處理器修改這個(gè)bean的BeanDefinition的一些定義。即調(diào)用MergedBeanDefinitionPostProcessor的實(shí)現(xiàn)類的postProcessMergedBeanDefinition方法對(duì)BeanDefinition進(jìn)行一些額外的處理。

為早期的循環(huán)依賴做準(zhǔn)備,將包裝了bean的工廠方法塞到singletonFactories中。

調(diào)用populateBean方法進(jìn)行一些屬性的注入。

執(zhí)行initializeBean方法進(jìn)行一些初始化方法的調(diào)用,例如:afterPropertiesSet方法的調(diào)用。與此同時(shí),其后置處理器有可能對(duì)指定的bean進(jìn)行增強(qiáng)。

如果出現(xiàn)了bean的增強(qiáng),然后又有依賴它的類先生成,則需拋出異常。例如:對(duì)象A被增強(qiáng)了,得到A+對(duì)象,而此時(shí)對(duì)象B有依賴對(duì)象A,循環(huán)依賴時(shí)通過singletonFactories獲取到的對(duì)象卻是增強(qiáng)前的A對(duì)象,這時(shí)就會(huì)出現(xiàn)問題。如果不拋出異常,spring容器緩存的是A+對(duì)象,但是B引用的卻是A,這樣就會(huì)出現(xiàn)不可預(yù)測(cè)的問題。

instantiateBean源碼

這里是createBeanInstance方法中最終調(diào)用的方法,這里有三個(gè)流程:

進(jìn)行對(duì)象的構(gòu)造,這里關(guān)注下CglibSubclassingInstantiationStrategy這個(gè)策略類,有繼承SimpleInstantiationStrategy類,調(diào)用其instantiate可以調(diào)用對(duì)象的構(gòu)造器進(jìn)行對(duì)象的初始化,在BeanDefinition屬性MethodOverrides不存在時(shí),可以用jdk的反射進(jìn)行獲取對(duì)象,否則則必須使用cglib動(dòng)態(tài)代理。(這里的MethodOverrides的存在需要對(duì)象中某個(gè)方法用@Lookup注解修飾,或者XML定義中有 lookup-method屬性

用BeanWrapperImpl對(duì)生成的對(duì)象進(jìn)行包裝,并激活注冊(cè)默認(rèn)編輯器的屬性。

注冊(cè)默認(rèn)的編輯器,然后將ConversionService這個(gè)類的引用設(shè)置到BeanWrapper對(duì)象上。ConversionService是用來進(jìn)行類型轉(zhuǎn)換的,里面的屬性converters用一個(gè)map維護(hù)著各種類型的轉(zhuǎn)換器。

populateBean源碼部分

下面關(guān)注幾個(gè)重點(diǎn)代碼,省略了一些代碼,可以自己去翻閱下:

protectedvoidpopulateBean(String?beanName,?RootBeanDefinition?mbd,?@Nullable?BeanWrapper?bw){

......

PropertyValues?pvs?=?(mbd.hasPropertyValues()???mbd.getPropertyValues()?:null);

if(mbd.getResolvedAutowireMode()?==?AUTOWIRE_BY_NAME?||?mbd.getResolvedAutowireMode()?==?AUTOWIRE_BY_TYPE)?{

MutablePropertyValues?newPvs?=newMutablePropertyValues(pvs);

//?這里是根據(jù)bean名稱進(jìn)行依賴注入的

if(mbd.getResolvedAutowireMode()?==?AUTOWIRE_BY_NAME)?{

autowireByName(beanName,?mbd,?bw,?newPvs);

}

//?這里是根據(jù)bean的類型進(jìn)行依賴注入的

if(mbd.getResolvedAutowireMode()?==?AUTOWIRE_BY_TYPE)?{

autowireByType(beanName,?mbd,?bw,?newPvs);

}

pvs?=?newPvs;

}

......

if(pvs?!=null)?{

//實(shí)際上注入屬性值的方法,這里是populateBean方法的重點(diǎn)

applyPropertyValues(beanName,?mbd,?bw,?pvs);

}

}

這里注釋下applyPropertyValues的部分源碼:

protectedvoidapplyPropertyValues(StringbeanName,?BeanDefinition?mbd,?BeanWrapper?bw,?PropertyValues?pvs)?{

MutablePropertyValues?mpvs?=null;

List?original;

if(pvsinstanceofMutablePropertyValues)?{

mpvs?=?(MutablePropertyValues)?pvs;

if(mpvs.isConverted())?{

//?這里可以迅速返回。當(dāng)這個(gè)PropertyValues對(duì)象中的值都是處理過后便可以觸發(fā)。狀態(tài)值會(huì)在下面幾行代碼設(shè)置。

try{

bw.setPropertyValues(mpvs);

return;

}

catch(BeansException?ex)?{

thrownewBeanCreationException(

mbd.getResourceDescription(),?beanName,"Error?setting?property?values",?ex);

}

}

original?=?mpvs.getPropertyValueList();

}

else{

original?=?Arrays.asList(pvs.getPropertyValues());

}

TypeConverter?converter?=?getCustomTypeConverter();

if(converter?==null)?{

converter?=?bw;

}

BeanDefinitionValueResolver?valueResolver?=newBeanDefinitionValueResolver(this,?beanName,?mbd,?converter);

//?這里是個(gè)深拷貝,解析所有引用的值。

List?deepCopy?=newArrayList<>(original.size());

boolean?resolveNecessary?=false;

for(PropertyValue?pv?:?original)?{

if(pv.isConverted())?{

deepCopy.add(pv);

}

else{

StringpropertyName?=?pv.getName();

ObjectoriginalValue?=?pv.getValue();

//這里的resolveValueIfNecessary是一個(gè)需要關(guān)注的方法,有興趣的小伙伴可以點(diǎn)進(jìn)去看看,

//里面封裝了針對(duì)各種類型的屬性的解析,例如List,Map,Set等等類型。

ObjectresolvedValue?=?valueResolver.resolveValueIfNecessary(pv,?originalValue);

ObjectconvertedValue?=?resolvedValue;

boolean?convertible?=?bw.isWritableProperty(propertyName)?&&

!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);

if(convertible)?{

convertedValue?=?convertForProperty(resolvedValue,?propertyName,?bw,?converter);

}

//為了避免每次創(chuàng)建都去轉(zhuǎn)換屬性

if(resolvedValue?==?originalValue)?{

//這里的觸發(fā)條件必須為該屬性得是有寫權(quán)限的,并且里面不能帶有“.”和“[”這個(gè)符號(hào),這里我的理解是

//teacher.name以及student[1].name這樣的propertyName便不能觸發(fā)這個(gè)條件

if(convertible)?{

pv.setConvertedValue(convertedValue);

}

deepCopy.add(pv);

}

elseif(convertible?&&?originalValueinstanceofTypedStringValue?&&

!((TypedStringValue)?originalValue).isDynamic()?&&

!(convertedValueinstanceofCollection?||?ObjectUtils.isArray(convertedValue)))?{

//這一塊的條件比上一個(gè)多了幾個(gè),源值必須是string類型,且不能是動(dòng)態(tài)的,并且不能是集合和數(shù)組中的任意一個(gè)。

pv.setConvertedValue(convertedValue);

deepCopy.add(pv);

}

else{

//條件在這里觸發(fā)后就不會(huì)打開快捷返回的開關(guān)了

resolveNecessary?=true;

deepCopy.add(newPropertyValue(pv,?convertedValue));

}

}

}

//設(shè)置converted狀態(tài)值,供其組裝屬性時(shí)快捷返回。

if(mpvs?!=null&&?!resolveNecessary)?{

mpvs.setConverted();

}

//?將我們深拷貝出來的值設(shè)置到包裝類BeanWrapperImpl包裝的對(duì)象上

try{

bw.setPropertyValues(newMutablePropertyValues(deepCopy));

}

catch(BeansException?ex)?{

thrownewBeanCreationException(

mbd.getResourceDescription(),?beanName,"Error?setting?property?values",?ex);

}

}

setPropertyValues方法的源碼最終調(diào)用的是AbstractNestablePropertyAccessor類的setPropertyValue方法,在這里BeanWrapperImpl是它的實(shí)現(xiàn)類,從名字上看也能猜出來這個(gè)類是個(gè)處理嵌套屬性的訪問器。

publicvoidsetPropertyValue(String?propertyName,?@Nullable?Objectvalue)?throws?BeansException{

AbstractNestablePropertyAccessor?nestedPa;

try{

//這里可以解析嵌套的屬性

nestedPa?=?getPropertyAccessorForPropertyPath(propertyName);

}

catch(NotReadablePropertyException?ex)?{

thrownewNotWritablePropertyException(getRootClass(),this.nestedPath?+?propertyName,

"Nested?property?in?path?'"+?propertyName?+"'?does?not?exist",?ex);

}

//這里獲取到了最終解析到的屬性名

PropertyTokenHolder?tokens?=?getPropertyNameTokens(getFinalPath(nestedPa,?propertyName));

//給最終解析到的屬性名賦值操作

nestedPa.setPropertyValue(tokens,newPropertyValue(propertyName,value));

}

上面有個(gè)getPropertyAccessorForPropertyPath方法,點(diǎn)進(jìn)去會(huì)發(fā)現(xiàn)他會(huì)有個(gè)解析“.”和“[]”的方法getNestedPropertySeparatorIndex,它的作用我舉個(gè)例子來說明一下:一個(gè)班級(jí)有多個(gè)學(xué)生,我想設(shè)置某個(gè)學(xué)生的名字,班級(jí)是個(gè)Class對(duì)象,里面有屬性:private Student[] students這里我想修改下student[2]的name屬性,我就必須先用getStudent方法取出 Student[] 數(shù)組,然后再在 Student[] 數(shù)組中找到索引為2的Student,最后修改Student身上的name屬性。

GetBean流程圖


在此我向大家推薦一個(gè)架構(gòu)學(xué)習(xí)交流群。交流學(xué)習(xí)群號(hào):938837867 暗號(hào):555 里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化、分布式架構(gòu)等這些成為架構(gòu)師必備

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容