?在網(wǎng)上已經(jīng)有跟多Bean的生命周期的博客橄杨,但是很多都是基于比較老的版本了竣况,最近吧整個(gè)流程化成了一個(gè)流程圖摹恨。待會(huì)兒使用流程圖,說(shuō)明以及代碼的形式來(lái)說(shuō)明整個(gè)聲明周期的流程娶视。注意因?yàn)榇a比較多晒哄,這里的流程圖只畫(huà)出了大概的流程,具體的可以深入代碼
1.獲取Bean
?這里的流程圖的入口在
AbstractBeanFactory
類(lèi)的doGetBean
方法肪获,這里可以配合前面的getBean方法分析文章進(jìn)行閱讀寝凌。主要流程就是
- 先處理Bean 的名稱(chēng),因?yàn)槿绻浴?amp;”開(kāi)頭的Bean名稱(chēng)表示獲取的是對(duì)應(yīng)的FactoryBean對(duì)象孝赫;
- 從緩存中獲取單例Bean较木,有則進(jìn)一步判斷這個(gè)Bean是不是在創(chuàng)建中,如果是的就等待創(chuàng)建完畢寒锚,否則直接返回這個(gè)Bean對(duì)象
- 如果不存在單例Bean緩存劫映,則先進(jìn)行循環(huán)依賴(lài)的解析
- 解析完畢之后先獲取父類(lèi)BeanFactory,獲取到了則調(diào)用父類(lèi)的getBean方法刹前,不存在則先合并然后創(chuàng)建Bean
2.創(chuàng)建Bean
2.1 創(chuàng)建Bean之前
?這個(gè)流程圖對(duì)應(yīng)的代碼在
AbstractAutowireCapableBeanFactory
類(lèi)的createBean
方法中。
- 這里會(huì)先獲取
RootBeanDefinition
對(duì)象中的Class對(duì)象并確保已經(jīng)關(guān)聯(lián)了要?jiǎng)?chuàng)建的Bean的Class雌桑。 - 這里會(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不是null還會(huì)調(diào)用實(shí)現(xiàn)的BeanPostProcessor
接口的postProcessAfterInitialization
方法邪驮,這里用代碼說(shuō)明
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//條件1
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//條件2跟條件3
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//調(diào)用實(shí)現(xiàn)的postProcessBeforeInstantiation方法
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//調(diào)用實(shí)現(xiàn)的postProcessAfterInitialization方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
//不滿(mǎn)足2或者3的時(shí)候就會(huì)設(shè)置為false
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
- 如果上面3個(gè)條件其中一個(gè)不滿(mǎn)足就不會(huì)調(diào)用實(shí)現(xiàn)的方法莫辨。默認(rèn)這里都不會(huì)調(diào)用的這些
BeanPostProcessors
的實(shí)現(xiàn)方法。然后繼續(xù)執(zhí)行后面的doCreateBean
方法。
2.1 真正的創(chuàng)建Bean沮榜,doCreateBean
這個(gè)代碼的實(shí)現(xiàn)還是在
AbstractAutowireCapableBeanFactory
方法中盘榨。流程是
- 先檢查
instanceWrapper
變量是不是null,這里一般是null蟆融,除非當(dāng)前正在創(chuàng)建的Bean在factoryBeanInstanceCache
中存在這個(gè)是保存還沒(méi)創(chuàng)建完成的FactoryBean的集合草巡。 - 調(diào)用createBeanInstance方法實(shí)例化Bean,這個(gè)方法在后面會(huì)講解
- 如果當(dāng)前
RootBeanDefinition
對(duì)象還沒(méi)有調(diào)用過(guò)實(shí)現(xiàn)了的MergedBeanDefinitionPostProcessor
接口的方法型酥,則會(huì)進(jìn)行調(diào)用 - 當(dāng)滿(mǎn)足以下三點(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
方法 - 調(diào)用
populateBean
方法進(jìn)行屬性填充山憨,這里后面會(huì)講解 - 調(diào)用
initializeBean
方法對(duì)Bean進(jìn)行初始化,這里后面會(huì)講解
2.1.1 實(shí)例化Bean弥喉,createBeanInstance
?這里的邏輯稍微有一點(diǎn)復(fù)雜萍歉,這個(gè)流程圖已經(jīng)是簡(jiǎn)化過(guò)后的了。簡(jiǎn)要根據(jù)代碼說(shuō)明一下流程
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//步驟1
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !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 != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//步驟3
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//步驟4.1
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
//步驟4.2
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
//步驟5
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
return instantiateBean(beanName, mbd);
}
- 先檢查Class是否已經(jīng)關(guān)聯(lián)了档桃,并且對(duì)應(yīng)的修飾符是否是public的
- 如果用戶(hù)定義了Bean實(shí)例化的函數(shù)枪孩,則調(diào)用并返回
- 如果當(dāng)前Bean實(shí)現(xiàn)了
FactoryBean
接口則調(diào)用對(duì)應(yīng)的FactoryBean
接口的getObject
方法 - 根據(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)造器州弟。
4.3 檢查4個(gè)條件是否滿(mǎn)足一個(gè)
(1)構(gòu)造器不為null钧栖,
(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ù)不是空
滿(mǎn)足其中一個(gè)則會(huì)調(diào)用返回的候選構(gòu)造器實(shí)例化Bean并返回婆翔,如果都不滿(mǎn)足拯杠,則會(huì)根據(jù)構(gòu)造參數(shù)選則合適的有參構(gòu)造器然后實(shí)例化Bean并返回 - 如果上面都沒(méi)有合適的構(gòu)造器,則直接使用無(wú)參構(gòu)造器創(chuàng)建并返回Bean啃奴。
2.1.2 填充Bean潭陪,populateBean
這里還是根據(jù)代碼來(lái)說(shuō)一下流程
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null 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() : null);
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 = null;
//步驟3
if (hasInstAwareBpps) {
if (pvs == null) {
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 == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
//步驟4
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
- 檢查當(dāng)前Bean是否實(shí)現(xiàn)了
InstantiationAwareBeanPostProcessor
的postProcessAfterInstantiation
方法則調(diào)用,并結(jié)束B(niǎo)ean的填充最蕾。 - 將按照類(lèi)型跟按照名稱(chēng)注入的Bean分開(kāi)依溯,如果注入的Bean還沒(méi)有實(shí)例化的這里會(huì)實(shí)例化,然后放到
PropertyValues
對(duì)象中瘟则。 - 如果實(shí)現(xiàn)了
InstantiationAwareBeanPostProcessor
類(lèi)的postProcessProperties
則調(diào)用這個(gè)方法并獲取返回值黎炉,如果返回值是null,則有可能是實(shí)現(xiàn)了過(guò)期的postProcessPropertyValues
方法醋拧,這里需要進(jìn)一步調(diào)用postProcessPropertyValues
方法 - 進(jìn)行參數(shù)填充
2.1.3 初始化Bean慷嗜,initializeBean
同時(shí)這里根據(jù)代碼跟流程圖來(lái)說(shuō)明
- 如果Bean實(shí)現(xiàn)了
BeanNameAware
,BeanClassLoaderAware
,BeanFactoryAware
則調(diào)用對(duì)應(yīng)實(shí)現(xiàn)的方法 - Bean不為null并且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 = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
- 實(shí)例化Bean然后,檢查是否實(shí)現(xiàn)了
InitializingBean
的afterPropertiesSet
方法忿峻,如果實(shí)現(xiàn)了就會(huì)調(diào)用 - Bean不為null并且bean不是合成的薄啥,如果實(shí)現(xiàn)了
BeanPostProcessor
的postProcessBeforeInitialization
則會(huì)調(diào)用實(shí)現(xiàn)的postProcessAfterInitialization
方法。
到此創(chuàng)建Bean 的流程就沒(méi)了逛尚,剩下的就是容器銷(xiāo)毀的時(shí)候的了
3.destory方法跟銷(xiāo)毀Bean
?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<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
.......
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != null && !(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<BeanPostProcessor> postProcessors, AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
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() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, 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);
}
}
}
......
}
4.總結(jié)。
最后來(lái)一個(gè)大的流程
關(guān)于Spring的BeanFactoryPostProcessor
跟BeanPostProcessor
后面會(huì)介紹