Spring Bean 的生命周期
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
76套java從入門(mén)到精通實(shí)戰(zhàn)課程分享
簡(jiǎn)要
Spring是一個(gè)IOC容器框架,擁有DI依賴(lài)注入(Dependency Injection),DL依賴(lài)查找(Dependency Lookup)等功能。
關(guān)于Spring Bean的生命周期,官方并沒(méi)有找到相關(guān)文檔。
下邊是我根據(jù)源碼分析出四個(gè)階段,做出的生命周期解讀:
注冊(cè)階段
實(shí)例化階段
初始化階段
銷(xiāo)毀階段

注冊(cè)階段
注冊(cè)階段主要任務(wù)是通過(guò)各種BeanDefinitionReader讀取掃描各種配置來(lái)源信息(xml文件、注解等),并轉(zhuǎn)換為BeanDefinition的過(guò)程。
BeanDefinition可以理解為類(lèi)的定義,描述一個(gè)類(lèi)的基本情況,比較像我們注冊(cè)某些網(wǎng)站時(shí)的基本信息,比如需要填寫(xiě)姓名、住址、出生日期等。
最終會(huì)將我們掃描到的類(lèi)整體注冊(cè)到一個(gè)DefaultListableBeanFactory的Map容器中,便于我們之后獲取使用。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
//存儲(chǔ)注冊(cè)信息的BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//beanDefinitionMap的數(shù)據(jù)結(jié)構(gòu)是ConcurrentHashMap,因此不能保證順序,為了記錄注冊(cè)的順序,這里使用了ArrayList類(lèi)型beanDefinitionNames用來(lái)記錄注冊(cè)順序
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
//省略部分代碼.......
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
//省略判斷代碼.......
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
}
}
實(shí)例化階段
在實(shí)例化階段,Spring主要將BeanDefinition轉(zhuǎn)換為實(shí)例Bean,并放在包裝類(lèi)BeanWrapper中。
無(wú)論是否設(shè)置Bean的懶加載方式,最后都會(huì)通過(guò)AbstractBeanFactory.getBean()方法進(jìn)行實(shí)例化,并進(jìn)入到AbstractAutowireCapableBeanFactory.createBean()方法。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
//省略部分代碼......
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//實(shí)例化前處理器
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//實(shí)例化后處理器
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
//省略部分代碼......
}
在實(shí)例化階段AbstractAutowireCapableBeanFactory.createBeanInstance()完成Bean的創(chuàng)建,并放到BeanWrapper中。
初始化階段
初始化階段主要是在返回Bean之前做一些處理,主要由AbstractAutowireCapableBeanFactory.initializeBean()方法實(shí)現(xiàn)。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
//省略部分代碼......
//真正創(chuàng)建Bean的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//省略部分代碼......
// Initialize the bean instance.
//Bean對(duì)象的初始化,依賴(lài)注入在此觸發(fā)
//這個(gè)exposedObject在初始化完成之后返回作為依賴(lài)注入完成后的Bean
Object exposedObject = bean;
try {
//將Bean實(shí)例對(duì)象封裝,并且Bean定義中配置的屬性值賦值給實(shí)例對(duì)象
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean對(duì)象
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
//省略部分代碼......
return exposedObject;
}
//初始容器創(chuàng)建的Bean實(shí)例對(duì)象,為其添加BeanPostProcessor后置處理器
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//JDK的安全機(jī)制驗(yàn)證權(quán)限
if (System.getSecurityManager() != null) {
//實(shí)現(xiàn)PrivilegedAction接口的匿名內(nèi)部類(lèi)
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//為Bean實(shí)例對(duì)象包裝相關(guān)屬性,如名稱(chēng),類(lèi)加載器,所屬容器等信息
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
//對(duì)BeanPostProcessor后置處理器的postProcessBeforeInitialization
//回調(diào)方法的調(diào)用,為Bean實(shí)例初始化前做一些處理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//調(diào)用Bean實(shí)例對(duì)象初始化的方法,這個(gè)初始化方法是在Spring Bean定義配置
//文件中通過(guò)init-method屬性指定的
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//對(duì)BeanPostProcessor后置處理器的postProcessAfterInitialization
//回調(diào)方法的調(diào)用,為Bean實(shí)例初始化之后做一些處理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
//省略部分代碼......
}
銷(xiāo)毀階段
一般是在ApplicationContext關(guān)閉的時(shí)候調(diào)用,也就是AbstractApplicationContext.close() 方法。
在注冊(cè)的時(shí)候Spring通過(guò)適配器模式包裝了一個(gè)類(lèi)DisposableBeanAdapter,在銷(xiāo)毀階段的時(shí)候會(huì)獲得這個(gè)類(lèi),進(jìn)而調(diào)用到DisposableBeanAdapter.destroy()方法:
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
//省略部分代碼......
@Override
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
if (this.invokeDisposableBean) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) bean).destroy();
return null;
}, acc);
}
else {
((DisposableBean) 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);
}
}
}
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod(this.destroyMethodName);
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
//省略部分代碼......
}
銷(xiāo)毀階段主要包括三個(gè)銷(xiāo)毀途徑,按照?qǐng)?zhí)行順序:
@PreDestroy注解,主要通過(guò)DestructionAwareBeanPostProcessor實(shí)現(xiàn)
實(shí)現(xiàn)DisposableBean接口,主要通過(guò)DisposableBean.destroy()實(shí)現(xiàn)
自定義銷(xiāo)毀方 DisposableBeanAdapter.invokeCustomDestroyMethod()實(shí)現(xiàn)
————————————————
版權(quán)聲明:本文為CSDN博主「武當(dāng)梯云縱」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/jeffYang1993/article/details/116153287
鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布
??????
??長(zhǎng)按上方微信二維碼 2 秒
感謝點(diǎn)贊支持下哈 
