基于springboot bean的實(shí)例化過(guò)程和屬性注入過(guò)程_第1頁(yè)
基于springboot bean的實(shí)例化過(guò)程和屬性注入過(guò)程_第2頁(yè)
基于springboot bean的實(shí)例化過(guò)程和屬性注入過(guò)程_第3頁(yè)
基于springboot bean的實(shí)例化過(guò)程和屬性注入過(guò)程_第4頁(yè)
基于springboot bean的實(shí)例化過(guò)程和屬性注入過(guò)程_第5頁(yè)
已閱讀5頁(yè),還剩10頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第基于springbootbean的實(shí)例化過(guò)程和屬性注入過(guò)程目錄bean的實(shí)例化過(guò)程和屬性注入過(guò)程bean實(shí)例化流程說(shuō)明

bean的實(shí)例化過(guò)程和屬性注入過(guò)程

了解過(guò)springboot的加載流程的都知道springboot初始化bean都在refresh方法中。

這個(gè)方法代碼如下:

//Preparethiscontextforrefreshing.

prepareRefresh();

//Tellthesubclasstorefreshtheinternalbeanfactory.新建beanFactory

ConfigurableListableBeanFactorybeanFactory=obtainFreshBeanFactory();

//Preparethebeanfactoryforuseinthiscontext.

prepareBeanFactory(beanFactory);

try{

//Allowspost-processingofthebeanfactoryincontextsubclasses.

postProcessBeanFactory(beanFactory);

//Invokefactoryprocessorsregisteredasbeansinthecontext.

//加載實(shí)現(xiàn)beanFactoryPostProcessor的bean,bean定義的時(shí)候執(zhí)行

invokeBeanFactoryPostProcessors(beanFactory);

//Registerbeanprocessorsthatinterceptbeancreation.

//加載實(shí)現(xiàn)了beanPostProcessor,在bean實(shí)例化前、后執(zhí)行

registerBeanPostProcessors(beanFactory);

//Initializemessagesourceforthiscontext.

initMessageSource();

//Initializeeventmulticasterforthiscontext.

initApplicationEventMulticaster();

//Initializeotherspecialbeansinspecificcontextsubclasses.

onRefresh();

//Checkforlistenerbeansandregisterthem.

registerListeners();

//Instantiateallremaining(non-lazy-init)singletons.

//實(shí)例化非懶加載的bean、bean封裝、屬性注入、注解注入(主要使用BeanPostProcessor或子類實(shí)現(xiàn))等

finishBeanFactoryInitialization(beanFactory);

//Laststep:publishcorrespondingevent.

finishRefresh();

這里我們主要看下finishBeanfactoryInitialization方法。此方法實(shí)現(xiàn)了bean的實(shí)例和屬性注入等。進(jìn)入此方法的最后一行。

//Instantiateallremaining(non-lazy-init)singletons.

beanFactory.preInstantiateSingletons();

注釋寫(xiě)的很清楚,實(shí)例化剩余非懶加載的bean。此方法的實(shí)現(xiàn)是核心類DefaultLisListableBeanFactory實(shí)現(xiàn)。這個(gè)方法中有個(gè)判斷:bean是否是beanFactory的實(shí)現(xiàn)類。

如果是則獲取bean的時(shí)候會(huì)從beanFactory實(shí)現(xiàn)類的getObject中獲取,我們重點(diǎn)看看getBean這個(gè)方法。

getBean是spring中最重要、最牛逼的方法之一,具體的邏輯是通過(guò)doGetBean方法處理的。

我們看下doGetBean方法,方法很長(zhǎng)。我們分成幾個(gè)部分去看。

1、先判斷是否已經(jīng)存在緩存中,代碼如下:

if(sharedInstance!=nullargs==null){

if(logger.isDebugEnabled()){

if(isSingletonCurrentlyInCreation(beanName)){

logger.debug("Returningeagerlycachedinstanceofsingletonbean'"+beanName+

"'thatisnotfullyinitializedyet-aconsequenceofacircularreference");

else{

logger.debug("Returningcachedinstanceofsingletonbean'"+beanName+"'");

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

2、從父beanfactory中獲取

BeanFactoryparentBeanFactory=getParentBeanFactory();

if(parentBeanFactory!=null!containsBeanDefinition(beanName)){

//Notfound-checkparent.

StringnameToLookup=originalBeanName(name);

if(parentBeanFactoryinstanceofAbstractBeanFactory){

return((AbstractBeanFactory)parentBeanFactory).doGetBean(

nameToLookup,requiredType,args,typeCheckOnly);

elseif(args!=null){

//Delegationtoparentwithexplicitargs.

return(T)parentBeanFactory.getBean(nameToLookup,args);

else{

//Noargs-delegatetostandardgetBeanmethod.

returnparentBeanFactory.getBean(nameToLookup,requiredType);

}

3、直接創(chuàng)建RootBeanDefinition

//mark給此bean馬克一下。防止重復(fù)創(chuàng)建

if(!typeCheckOnly){

markBeanAsCreated(beanName);

try{

finalRootBeanDefinitionmbd=getMergedLocalBeanDefinition(beanName);

checkMergedBeanDefinition(mbd,beanName,args);

//Guaranteeinitializationofbeansthatthecurrentbeandependson.

String[]dependsOn=mbd.getDependsOn();

if(dependsOn!=null){

for(Stringdep:dependsOn){

if(isDependent(beanName,dep)){

thrownewBeanCreationException(mbd.getResourceDescription(),beanName,

"Circulardepends-onrelationshipbetween'"+beanName+"'and'"+dep+"'");

registerDependentBean(dep,beanName);

getBean(dep);

4、是singleton還是prototype類型的,根據(jù)不同類型去實(shí)例化bean,代碼只貼了單例的類型:

//Createbeaninstance.

if(mbd.isSingleton()){

sharedInstance=getSingleton(beanName,()-{

try{

returncreateBean(beanName,mbd,args);

catch(BeansExceptionex){

//Explicitlyremoveinstancefromsingletoncache:Itmighthavebeenputthere

//eagerlybythecreationprocess,toallowforcircularreferenceresolution.

//Alsoremoveanybeansthatreceivedatemporaryreferencetothebean.

destroySingleton(beanName);

throwex;

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

5、檢查bean的類型是否匹配

//Checkifrequiredtypematchesthetypeoftheactualbeaninstance.

if(requiredType!=null!requiredType.isInstance(bean)){

try{

TconvertedBean=getTypeConverter().convertIfNecessary(bean,requiredType);

if(convertedBean==null){

thrownewBeanNotOfRequiredTypeException(name,requiredType,bean.getClass());

returnconvertedBean;

catch(TypeMismatchExceptionex){

if(logger.isDebugEnabled()){

logger.debug("Failedtoconvertbean'"+name+"'torequiredtype'"+

ClassUtils.getQualifiedName(requiredType)+"'",ex);

thrownewBeanNotOfRequiredTypeException(name,requiredType,bean.getClass());

}

整個(gè)doGetBean方法改成這5個(gè)部分,重點(diǎn)看下第4個(gè)部分中的createBean和getObjectForBeanInstance方法。

1、createBean方法,里面主要是2個(gè)部分,bean直接是通過(guò)BeanPostProcessor的postProcessBeforeIntantiation方法獲取的。

注釋也是描述的很清楚:GiveBeanPostProcessorsachancetoreturnaproxyinsteadofthebeaninstance(英語(yǔ)渣渣不敢瞎翻譯誤導(dǎo)大家,理解就好)

代碼如下:

try{

//GiveBeanPostProcessorsachancetoreturnaproxyinsteadofthetargetbeaninstance.

Objectbean=resolveBeforeInstantiation(beanName,mbdToUse);

if(bean!=null){

returnbean;

catch(Throwableex){

thrownewBeanCreationException(mbdToUse.getResourceDescription(),beanName,

"BeanPostProcessorbeforeinstantiationofbeanfailed",ex);

第一個(gè)部分自己實(shí)現(xiàn),那么createBean方法第2個(gè)部分毋庸置疑肯定是spring去實(shí)例化bean,代碼如下:

try{

ObjectbeanInstance=doCreateBean(beanName,mbdToUse,args);

if(logger.isDebugEnabled()){

logger.debug("Finishedcreatinginstanceofbean'"+beanName+"'");

returnbeanInstance;

}

又是do開(kāi)頭的方法,說(shuō)明這個(gè)也是一個(gè)創(chuàng)建方法,spring中一般do開(kāi)頭的都是用于創(chuàng)建某個(gè)對(duì)象。跟著代碼走,看下doCreateBean方法,在查看此方法之前,可能需要了解下BeanWarpper這個(gè)封裝類。bean的封裝、屬性注入等都是用BeanWarpper去完成的。

看下代碼:

//Instantiatethebean.

BeanWrapperinstanceWrapper=null;

if(mbd.isSingleton()){

instanceWrapper=this.factoryBeanInstanceCache.remove(beanName);

if(instanceWrapper==null){

instanceWrapper=createBeanInstance(beanName,mbd,args);

}

進(jìn)入createBeanInstance方法中,就是調(diào)用構(gòu)造器去實(shí)例化bean,返回beanWrapper。通過(guò)構(gòu)造器獲取實(shí)例代碼如下:

//Needtodeterminetheconstructor...

Constructor[]ctors=determineConstructorsFromBeanPostProcessors(beanClass,beanName);

if(ctors!=null||

mbd.getResolvedAutowireMode()==RootBeanDefinition.AUTOWIRE_CONSTRUCTOR||

mbd.hasConstructorArgumentValues()||!ObjectUtils.isEmpty(args)){

returnautowireConstructor(beanName,mbd,ctors,args);

//Nospecialhandling:simplyuseno-argconstructor.

returninstantiateBean(beanName,mbd);

這里實(shí)例化我一開(kāi)始以為就是簡(jiǎn)單的反射,后面我點(diǎn)進(jìn)去時(shí)候發(fā)現(xiàn)里面一直提策略實(shí)例化,我目前了解的是可以解決Override的問(wèn)題等。如果有興趣的可以自行查看。到這里為止。我們終于實(shí)例化bean了。下面看下第二步bean的屬性注入等。

代碼如下:

ObjectexposedObject=bean;

try{

populateBean(beanName,mbd,instanceWrapper);

exposedObject=initializeBean(beanName,exposedObject,mbd);

catch(Throwableex){

if(exinstanceofBeanCreationExceptionbeanName.equals(((BeanCreationException)ex).getBeanName())){

throw(BeanCreationException)ex;

else{

thrownewBeanCreationException(

mbd.getResourceDescription(),beanName,"Initializationofbeanfailed",ex);

}

populateBean方法名稱就暴露他是干啥的:填充bean。我放一段比較重要的部分:

if(hasInstAwareBpps||needsDepCheck){

if(pvs==null){

pvs=mbd.getPropertyValues();

PropertyDescriptor[]filteredPds=filterPropertyDescriptorsForDependencyCheck(bw,mbd.allowCaching);

if(hasInstAwareBpps){

for(BeanPostProcessorbp:getBeanPostProcessors()){

if(bpinstanceofInstantiationAwareBeanPostProcessor){

InstantiationAwareBeanPostProcessoribp=(InstantiationAwareBeanPostProcessor)bp;

pvs=ibp.postProcessPropertyValues(pvs,filteredPds,bw.getWrappedInstance(),beanName);

if(pvs==null){

return;

if(needsDepCheck){

checkDependencies(beanName,mbd,filteredPds,pvs);

}

這段代碼貌似沒(méi)有什么注入、填充什么的,我們看下InstantiationAwareBeanPostProcessor這個(gè)接口,發(fā)現(xiàn)這個(gè)接口有個(gè)很熟悉的實(shí)現(xiàn)類是:AutowiredAnnotationBeanPostProcessor。這個(gè)類的方法中我們看到終于看到了jnject方法。但是在inject之前需要調(diào)用下findAutowiringMatedata方法獲取一下元數(shù)據(jù):

//Fallbacktoclassnameascachekey,forbackwardscompatibilitywithcustomcallers.

StringcacheKey=(StringUtils.hasLength(beanName)beanName:clazz.getName());

//Quickcheckontheconcurrentmapfirst,withminimallocking.

InjectionMetadatametadata=this.injectionMetadataCache.get(cacheKey);

if(InjectionMetadata.needsRefresh(metadata,clazz)){

synchronized(this.injectionMetadataCache){

metadata=this.injectionMetadataCache.get(cacheKey);

if(InjectionMetadata.needsRefresh(metadata,clazz)){

if(metadata!=null){

metadata.clear(pvs);

metadata=buildAutowiringMetadata(clazz);

this.injectionMetadataCache.put(cacheKey,metadata);

returnmetadata;

那么問(wèn)題又來(lái)了,這個(gè)injectionMetadataCache集合值是從那里來(lái)的呢?AutowiredAnnotationBeanPostProcessor實(shí)現(xiàn)了MergeBeandefinitionPostProcessor,那么就好了,肯定是在bean實(shí)例的時(shí)候調(diào)用了postProcessMergedBeanDefintion這個(gè)方法。

果然在doCreateBean方法中有這么一段:

//Allowpost-processorstomodifythemergedbeandefinition.

synchronized(mbd.postProcessingLock){

if(!mbd.postProcessed){

try{

//通過(guò)BeanPostProcessor將需要注解的元數(shù)據(jù)放到Map中

applyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName);

catch(Throwableex){

thrownewBeanCreationException(mbd.getResourceDescription(),beanName,

"Post-processingofmergedbeandefinitionfailed",ex);

mbd.postProcessed=true;

}

哎,spring縝密啊。元數(shù)據(jù)有了,下面我們看下element.inject()方法是如何操作的:

if(this.isField){

Fieldfield=(Field)this.member;

ReflectionUtils.makeAccessible(field);

field.set(target,getResourceToInject(target,requestingBeanName));

else{

if(checkPropertySkipping(pvs)){

return;

try{

Methodmethod=(Method)this.member;

ReflectionUtils.makeAccessible(method);

method.invoke(target,getResourceToInject(target,requestingBeanName));

catch(InvocationTargetExceptionex){

throwex.getTargetException();

}

方法簡(jiǎn)單明了,直接使用反射將值set到屬性中,至此bean的實(shí)例、屬性注入基本完成,下面我們回頭來(lái)看doGetBean的另一個(gè)方法getObjectForBeanInstance。

2、getObjectForBeanInstance方法。對(duì)于是FactoryBean類型的bean通過(guò)getObject獲取到bean的代理實(shí)例,跟著方法一直走下去會(huì)到getObejct()方法中。

if(System.getSecurityManager()!=null){

AccessControlContextacc=getAccessControlContext();

try{

object=AccessController.doPrivileged((PrivilegedExceptionActionObject)factory::getObject,acc);

catch(PrivilegedActionExceptionpae){

throwpae.getException();

else{

//從FactoryBean實(shí)現(xiàn)bean中g(shù)etObejct獲取到bean

object=factory.getObject();

}

到此finishBeanfactoryInitialization方法執(zhí)行結(jié)束!

bean實(shí)例化流程說(shuō)明

bean實(shí)例化流程流程是在onRefresh方法的finishBeanFactoryInitialization中。進(jìn)入該方法

protectedvoidfinishBeanFactoryInitialization(ConfigurableListableBeanFactorybeanFactory){

//Initializeconversionserviceforthiscontext.

if(beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)

beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME,ConversionService.class)){

beanFactory.setConversionServi

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論