Spring Bean 的生命周期
點擊上方藍色字體,選擇“標星公眾號”
優(yōu)質文章,第一時間送達
簡要
Spring是一個IOC容器框架,擁有DI依賴注入(Dependency Injection),DL依賴查找(Dependency Lookup)等功能。
關于Spring Bean的生命周期,官方并沒有找到相關文檔。
下邊是我根據源碼分析出四個階段,做出的生命周期解讀:
注冊階段
實例化階段
初始化階段
銷毀階段

注冊階段
注冊階段主要任務是通過各種BeanDefinitionReader讀取掃描各種配置來源信息(xml文件、注解等),并轉換為BeanDefinition的過程。
BeanDefinition可以理解為類的定義,描述一個類的基本情況,比較像我們注冊某些網站時的基本信息,比如需要填寫姓名、住址、出生日期等。
最終會將我們掃描到的類整體注冊到一個DefaultListableBeanFactory的Map容器中,便于我們之后獲取使用。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
//存儲注冊信息的BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//beanDefinitionMap的數據結構是ConcurrentHashMap,因此不能保證順序,為了記錄注冊的順序,這里使用了ArrayList類型beanDefinitionNames用來記錄注冊順序
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);
}
}
實例化階段
在實例化階段,Spring主要將BeanDefinition轉換為實例Bean,并放在包裝類BeanWrapper中。
無論是否設置Bean的懶加載方式,最后都會通過AbstractBeanFactory.getBean()方法進行實例化,并進入到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) {
//實例化前處理器
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//實例化后處理器
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
//省略部分代碼......
}
在實例化階段AbstractAutowireCapableBeanFactory.createBeanInstance()完成Bean的創(chuàng)建,并放到BeanWrapper中。
初始化階段
初始化階段主要是在返回Bean之前做一些處理,主要由AbstractAutowireCapableBeanFactory.initializeBean()方法實現。
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對象的初始化,依賴注入在此觸發(fā)
//這個exposedObject在初始化完成之后返回作為依賴注入完成后的Bean
Object exposedObject = bean;
try {
//將Bean實例對象封裝,并且Bean定義中配置的屬性值賦值給實例對象
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean對象
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實例對象,為其添加BeanPostProcessor后置處理器
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//JDK的安全機制驗證權限
if (System.getSecurityManager() != null) {
//實現PrivilegedAction接口的匿名內部類
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//為Bean實例對象包裝相關屬性,如名稱,類加載器,所屬容器等信息
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
//對BeanPostProcessor后置處理器的postProcessBeforeInitialization
//回調方法的調用,為Bean實例初始化前做一些處理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//調用Bean實例對象初始化的方法,這個初始化方法是在Spring Bean定義配置
//文件中通過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);
}
//對BeanPostProcessor后置處理器的postProcessAfterInitialization
//回調方法的調用,為Bean實例初始化之后做一些處理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
//省略部分代碼......
}
銷毀階段
一般是在ApplicationContext關閉的時候調用,也就是AbstractApplicationContext.close() 方法。
在注冊的時候Spring通過適配器模式包裝了一個類DisposableBeanAdapter,在銷毀階段的時候會獲得這個類,進而調用到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);
}
}
}
//省略部分代碼......
}
銷毀階段主要包括三個銷毀途徑,按照執(zhí)行順序:
@PreDestroy注解,主要通過DestructionAwareBeanPostProcessor實現
實現DisposableBean接口,主要通過DisposableBean.destroy()實現
自定義銷毀方 DisposableBeanAdapter.invokeCustomDestroyMethod()實現
————————————————
版權聲明:本文為CSDN博主「武當梯云縱」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/jeffYang1993/article/details/116153287
鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布
??????
??長按上方微信二維碼 2 秒
感謝點贊支持下哈 
