優(yōu)質(zhì)文章,及時(shí)送達(dá)
編輯 | Java之間(gengecn)
來(lái)源 | tech.souyunku.com/?p=13107
在網(wǎng)上已經(jīng)有跟多Bean的生命周期的博客,但是很多都是基于比較老的版本了,最近吧整個(gè)流程化成了一個(gè)流程圖。待會(huì)兒使用流程圖,說(shuō)明以及代碼的形式來(lái)說(shuō)明整個(gè)聲明周期的流程。注意因?yàn)榇a比較多,這里的流程圖只畫(huà)出了大概的流程,具體的可以深入代碼
一、獲取Bea
第一階段獲取Bean
這里的流程圖的入口在 AbstractBeanFactory
類(lèi)的doGetBean
方法,這里可以配合前面的 getBean方法分析文章進(jìn)行閱讀。主要流程就是
1、先處理Bean 的名稱(chēng),因?yàn)槿绻浴?”開(kāi)頭的Bean名稱(chēng)表示獲取的是對(duì)應(yīng)的FactoryBean對(duì)象;
2、從緩存中獲取單例Bean,有則進(jìn)一步判斷這個(gè)Bean是不是在創(chuàng)建中,如果是的就等待創(chuàng)建完畢,否則直接返回這個(gè)Bean對(duì)象
3、如果不存在單例Bean緩存,則先進(jìn)行循環(huán)依賴(lài)的解析
4、解析完畢之后先獲取父類(lèi)BeanFactory,獲取到了則調(diào)用父類(lèi)的getBean方法,不存在則先合并然后創(chuàng)建Bean
二、創(chuàng)建Bean
2.1 創(chuàng)建Bean之前
在真正創(chuàng)建Bean之前邏輯
這個(gè)流程圖對(duì)應(yīng)的代碼在 AbstractAutowireCapableBeanFactory
類(lèi)的createBean
方法中。
1、這里會(huì)先獲取RootBeanDefinition
對(duì)象中的Class對(duì)象并確保已經(jīng)關(guān)聯(lián)了要?jiǎng)?chuàng)建的Bean的Class 。整編:微信公眾號(hào),搜云庫(kù)技術(shù)團(tuán)隊(duì),ID:souyunku
2、這里會(huì)檢查3個(gè)條件
(1)Bean的屬性中的 beforeInstantiationResolved
字段是否為true,默認(rèn)是false。
(2)Bean是原生的Bean
(3)Bean的 hasInstantiationAwareBeanPostProcessors
屬性為true,這個(gè)屬性在Spring準(zhǔn)備刷新容器錢(qián)轉(zhuǎn)杯BeanPostProcessors的時(shí)候會(huì)設(shè)置,如果當(dāng)前Bean實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor
則這個(gè)就會(huì)是true。
當(dāng)三個(gè)條件都存在的時(shí)候,就會(huì)調(diào)用實(shí)現(xiàn)的 InstantiationAwareBeanPostProcessor
接口的postProcessBeforeInstantiation
方法,然后獲取返回的Bean,如果返回的Bean不是還會(huì)調(diào)用實(shí)現(xiàn)的BeanPostProcessor
接口的postProcessAfterInitialization
方法,這里用代碼說(shuō)明
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = ;
//條件1
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//條件2跟條件3
if (!mbd.isSynthetic && hasInstantiationAwareBeanPostProcessors) {
Class> targetType = determineTargetType(beanName, mbd);
if (targetType != ) {
//調(diào)用實(shí)現(xiàn)的postProcessBeforeInstantiation方法
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != ) {
//調(diào)用實(shí)現(xiàn)的postProcessAfterInitialization方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
//不滿足2或者3的時(shí)候就會(huì)設(shè)置為false
mbd.beforeInstantiationResolved = (bean != );
}
return bean;
}
1、如果上面3個(gè)條件其中一個(gè)不滿足就不會(huì)調(diào)用實(shí)現(xiàn)的方法。默認(rèn)這里都不會(huì)調(diào)用的這些BeanPostProcessors
的實(shí)現(xiàn)方法。然后繼續(xù)執(zhí)行后面的doCreateBean
方法。
2.1 真正的創(chuàng)建Bean,doCreateBean
doCreateBean方法邏輯
這個(gè)代碼的實(shí)現(xiàn)還是在 AbstractAutowireCapableBeanFactory
方法中。流程是
1、先檢查instanceWrapper
變量是不是,這里一般是,除非當(dāng)前正在創(chuàng)建的Bean在factoryBeanInstanceCache
中存在這個(gè)是保存還沒(méi)創(chuàng)建完成的FactoryBean的集合。
2、調(diào)用createBeanInstance方法實(shí)例化Bean,這個(gè)方法在后面會(huì)講解
3、如果當(dāng)前RootBeanDefinition
對(duì)象還沒(méi)有調(diào)用過(guò)實(shí)現(xiàn)了的MergedBeanDefinitionPostProcessor
接口的方法,則會(huì)進(jìn)行調(diào)用 。整編:微信公眾號(hào),搜云庫(kù)技術(shù)團(tuán)隊(duì),ID:souyunku
4、 當(dāng)滿足以下三點(diǎn)
(1)是單例Bean
(2)嘗試解析bean之間的循環(huán)引用
(3)bean目前正在創(chuàng)建中
則會(huì)進(jìn)一步檢查是否實(shí)現(xiàn)了 SmartInstantiationAwareBeanPostProcessor
接口如果實(shí)現(xiàn)了則調(diào)用是實(shí)現(xiàn)的getEarlyBeanReference
方法 5、 調(diào)用populateBean
方法進(jìn)行屬性填充,這里后面會(huì)講解 6、 調(diào)用initializeBean
方法對(duì)Bean進(jìn)行初始化,這里后面會(huì)講解
2.1.1 實(shí)例化Bean,createBeanInstance
實(shí)例化Bean
這里的邏輯稍微有一點(diǎn)復(fù)雜,這個(gè)流程圖已經(jīng)是簡(jiǎn)化過(guò)后的了。簡(jiǎn)要根據(jù)代碼說(shuō)明一下流程
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @ableObject[] args) {
//步驟1
Class> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != && !Modifier.isPublic(beanClass.getModifiers) && !mbd.isNonPublicAccessAllowed) {
throw new BeanCreationException(mbd.getResourceDescription, beanName,
"Bean class isn't public, and non-public access not allowed: "+ beanClass.getName);
}
//步驟2
Supplier> instanceSupplier = mbd.getInstanceSupplier;
if (instanceSupplier != ) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//步驟3
if (mbd.getFactoryMethodName != ) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
boolean resolved = false;
boolean autowireNecessary = false;
if (args == ) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != ) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//步驟4.1
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, , );
}
else {
return instantiateBean(beanName, mbd);
}
}
//步驟4.2
Constructor> ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != || mbd.getResolvedAutowireMode == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
//步驟5
ctors = mbd.getPreferredConstructors;
if (ctors != ) {
return autowireConstructor(beanName, mbd, ctors, );
}
return instantiateBean(beanName, mbd);
}
1、先檢查Class是否已經(jīng)關(guān)聯(lián)了,并且對(duì)應(yīng)的修飾符是否是public的
2、如果用戶(hù)定義了Bean實(shí)例化的函數(shù),則調(diào)用并返回
3、如果當(dāng)前Bean實(shí)現(xiàn)了FactoryBean
接口則調(diào)用對(duì)應(yīng)的FactoryBean
接口的getObject
方法
4、根據(jù)getBean時(shí)候是否傳入構(gòu)造參數(shù)進(jìn)行處理
4.1如果沒(méi)有傳入構(gòu)造參數(shù),則檢查是否存在已經(jīng)緩存的無(wú)參構(gòu)造器,有則使用構(gòu)造器直接創(chuàng)建,沒(méi)有就會(huì)調(diào)用instantiateBean
方法先獲取實(shí)例化的策略默認(rèn)是CglibSubclassingInstantiationStrategy
,然后實(shí)例化Bean。最后返回
4.2如果傳入了構(gòu)造參數(shù),則會(huì)先檢查是否實(shí)現(xiàn)了SmartInstantiationAwareBeanPostProcessor
接口,如果實(shí)現(xiàn)了會(huì)調(diào)用determineCandidateConstructors
獲取返回的候選構(gòu)造器。整編:微信公眾號(hào),搜云庫(kù)技術(shù)團(tuán)隊(duì),ID:souyunku
4.3檢查4個(gè)條件是否滿足一個(gè)
(1)構(gòu)造器不為,
(2)從RootBeanDefinition中獲取到的關(guān)聯(lián)的注入方式是構(gòu)造器注入(沒(méi)有構(gòu)造參數(shù)就是setter注入,有則是構(gòu)造器注入)
(3)含有構(gòu)造參數(shù)
(4)getBean方法傳入構(gòu)造參數(shù)不是空
滿足其中一個(gè)則會(huì)調(diào)用返回的候選構(gòu)造器實(shí)例化Bean并返回,如果都不滿足,則會(huì)根據(jù)構(gòu)造參數(shù)選則合適的有參構(gòu)造器然后實(shí)例化Bean并返回
5、如果上面都沒(méi)有合適的構(gòu)造器,則直接使用無(wú)參構(gòu)造器創(chuàng)建并返回Bean。
2.1.2 填充Bean,populateBean
填充Bean
這里還是根據(jù)代碼來(lái)說(shuō)一下流程
protected void populateBean(String beanName, RootBeanDefinition mbd, @ableBeanWrapper bw) {
if (bw == ) {
if (mbd.hasPropertyValues) {
throw new BeanCreationException(
mbd.getResourceDescription, beanName, "Cannot apply property values to instance");
}
else {
// Skip property population phase for instance.
return;
}
}
boolean continueWithPropertyPopulation = true;
//步驟1
if (!mbd.isSynthetic && hasInstantiationAwareBeanPostProcessors) {
for (BeanPostProcessor bp : getBeanPostProcessors) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance, beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
//步驟2--------------------
PropertyValues pvs = (mbd.hasPropertyValues ? mbd.getPropertyValues : );
int resolvedAutowireMode = mbd.getResolvedAutowireMode;
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors;
boolean needsDepCheck = (mbd.getDependencyCheck != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor filteredPds = ;
//步驟3
if (hasInstAwareBpps) {
if (pvs == ) {
pvs = mbd.getPropertyValues;
}
for (BeanPostProcessor bp : getBeanPostProcessors) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance, beanName);
if (pvsToUse == ) {
if (filteredPds == ) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance, beanName);
if (pvsToUse == ) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == ) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
//步驟4
if (pvs != ) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
1、檢查當(dāng)前Bean是否實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor
的postProcessAfterInstantiation
方法則調(diào)用,并結(jié)束B(niǎo)ean的填充。
2、將按照類(lèi)型跟按照名稱(chēng)注入的Bean分開(kāi),如果注入的Bean還沒(méi)有實(shí)例化的這里會(huì)實(shí)例化,然后放到PropertyValues
對(duì)象中。
3、如果實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor
類(lèi)的postProcessProperties
則調(diào)用這個(gè)方法并獲取返回值,如果返回值是,則有可能是實(shí)現(xiàn)了過(guò)期的postProcessPropertyValues
方法,這里需要進(jìn)一步調(diào)用postProcessPropertyValues
方法
4、進(jìn)行參數(shù)填充
2.1.3 初始化Bean,initializeBean
初始化Bean
同時(shí)這里根據(jù)代碼跟流程圖來(lái)說(shuō)明
1、如果Bean實(shí)現(xiàn)了BeanNameAware
,BeanClassLoaderAware
,BeanFactoryAware
則調(diào)用對(duì)應(yīng)實(shí)現(xiàn)的方法 。整編:微信公眾號(hào),搜云庫(kù)技術(shù)團(tuán)隊(duì),ID:souyunku
2、Bean不為并且bean不是合成的,如果實(shí)現(xiàn)了BeanPostProcessor
的postProcessBeforeInitialization
則會(huì)調(diào)用實(shí)現(xiàn)的postProcessBeforeInitialization
方法。在ApplicationContextAwareProcessor
類(lèi)中實(shí)現(xiàn)了postProcessBeforeInitialization
方法。而這個(gè)類(lèi)會(huì)在Spring刷新容器準(zhǔn)備beanFactory
的時(shí)候會(huì)加進(jìn)去,這里就會(huì)被調(diào)用,而調(diào)用里面會(huì)檢查Bean是不是EnvironmentAware
,EmbeddedValueResolverAware
,ResourceLoaderAware
,ApplicationEventPublisherAware
,MessageSourceAware
,ApplicationContextAware
的實(shí)現(xiàn)類(lèi)。這里就會(huì)調(diào)用對(duì)應(yīng)的實(shí)現(xiàn)方法。代碼如下
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
.......
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
.......
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}
AccessControlContext acc = ;
if (System.getSecurityManager != ) {
acc = this.applicationContext.getBeanFactory.getAccessControlContext;
}
if (acc != ) {
AccessController.doPrivileged((PrivilegedAction
invokeAwareInterfaces(bean);
return ;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
1、實(shí)例化Bean然后,檢查是否實(shí)現(xiàn)了InitializingBean
的afterPropertiesSet
方法,如果實(shí)現(xiàn)了就會(huì)調(diào)用
2、Bean不為并且bean不是合成的,如果實(shí)現(xiàn)了BeanPostProcessor
的postProcessBeforeInitialization
則會(huì)調(diào)用實(shí)現(xiàn)的postProcessAfterInitialization
方法。
到此創(chuàng)建Bean 的流程就沒(méi)了,剩下的就是容器銷(xiāo)毀的時(shí)候的了
三、destory方法跟銷(xiāo)毀Bean
歡迎關(guān)注公眾號(hào):Java后端
Bean在創(chuàng)建完畢之后會(huì)檢查用戶(hù)是否指定了 destroyMethodName
以及是否實(shí)現(xiàn)了DestructionAwareBeanPostProcessor
接口的requiresDestruction
方法,如果指定了會(huì)記錄下來(lái)保存在DisposableBeanAdapter
對(duì)象中并保存在bean的disposableBeans
屬性中。代碼在AbstractBeanFactory
的registerDisposableBeanIfNecessary
中
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
......
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors, acc));
......
}
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List
postProcessors, @ableAccessControlContext acc) {
.......
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
......
this.destroyMethod = destroyMethod;
}
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
在銷(xiāo)毀Bean的時(shí)候最后都會(huì)調(diào)用 AbstractAutowireCapableBeanFactory
的destroyBean
方法。
public void destroyBean(Object existingBean) {
new DisposableBeanAdapter(existingBean, getBeanPostProcessors, getAccessControlContext).destroy;
}
這里是創(chuàng)建一個(gè) DisposableBeanAdapter
對(duì)象,這個(gè)對(duì)象實(shí)現(xiàn)了Runnable接口,在實(shí)現(xiàn)的run
方法中會(huì)調(diào)用實(shí)現(xiàn)的DisposableBean
接口的destroy
方法。并且在創(chuàng)建DisposableBeanAdapter
對(duì)象的時(shí)候會(huì)根據(jù)傳入的bean是否實(shí)現(xiàn)了DisposableBean
接口來(lái)設(shè)置invokeDisposableBean
變量,這個(gè)變量表實(shí)有沒(méi)有實(shí)現(xiàn)DisposableBean
接口
public DisposableBeanAdapter(Object bean, List
postProcessors, AccessControlContext acc) {
Assert.not(bean, "Disposable bean must not be ");
this.bean = bean;
this.beanName = bean.getClass.getName;
//根據(jù)傳入的bean是否實(shí)現(xiàn)了`DisposableBean`接口來(lái)設(shè)置`invokeDisposableBean`變量
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
this.nonPublicAccessAllowed = true;
this.acc = acc;
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
public void destroy {
......
//根據(jù)invokeDisposableBean決定是否調(diào)用destroy方法
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled) {
logger.trace("Invoking destroy on bean with name '"+ this.beanName +"'");
}
try {
if (System.getSecurityManager != ) {
AccessController.doPrivileged((PrivilegedExceptionAction
((DisposableBean) this.bean).destroy;
return ;
}, this.acc);
}
else {
((DisposableBean) this.bean).destroy;
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '"+ this.beanName +"'";
if (logger.isDebugEnabled) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": "+ ex);
}
}
}
......
}
四、總結(jié)。
最后來(lái)一個(gè)大的流程
實(shí)例化前的準(zhǔn)備階段
實(shí)例化前
實(shí)例化后
初始化前
-END-
(正文已結(jié)束)
推薦閱讀:天津紅橋網(wǎng)
免責(zé)聲明及提醒:此文內(nèi)容為本網(wǎng)所轉(zhuǎn)載企業(yè)宣傳資訊,該相關(guān)信息僅為宣傳及傳遞更多信息之目的,不代表本網(wǎng)站觀點(diǎn),文章真實(shí)性請(qǐng)瀏覽者慎重核實(shí)!任何投資加盟均有風(fēng)險(xiǎn),提醒廣大民眾投資需謹(jǐn)慎!