浅谈spring bean的生命周期
生命周期,简单理解就是事物从开始出现到最终消亡的一段时间。spring bean的生命周期就是从spring创建bean,到最终spring将bean销毁的一个过程(或一段时间),而我们上篇谈到的spring bean的初始化方法和销毁方法,都会在bean的生命周期内得到调用。简单来说,spring容器中的bean会经历如下过程:
创建bean实例-->创建完成,正常使用-->spring销毁bean
接下来我们就基于spring 5.3.20版本的代码对上述过程详细分析下。
1、代码跟踪
spring容器启动的时候,会调用org.springframework.context.support.AbstractApplicationContext#refresh。其中refresh方法实现如下:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// 本篇的关注点,实例化所有非懒加载的单例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
本次我们关注其中的finishBeanFactoryInitialization 方法,看下方法的最后一行代码:
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
跟踪preInstantiateSingletons方法,最终会经历如下的流程来创建bean。
1.1、AbstractBeanFactory#getBean(java.lang.String)
1.2、AbstractBeanFactory#doGetBean
1.3、AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
1.4、AbstractAutowireCapableBeanFactory#doCreateBean
最终由步骤1.4完成bean的创建。
2、创建bean
分析1.4步骤的doCreateBean方法,我们可以得出如下bean的创建过程。
创建bean实例-->填充bean属性-->初始化bean
2.1、创建bean实例
本过程的实现对应createBeanInstance方法,该方法根据bean定义信息,采取合适的策略(指定的工厂方法、构造器注入或使用无参构造器)创建bean对象。
2.2、填充bean属性
本过程的实现对应populateBean方法,完成bean的属性的赋值操作。
2.3、初始化bean
本过程的实现对应initializeBean方法,initializeBean方法实现如下:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//调用各种aware接口方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用所有的BeanPostProcessor对象的postProcessBeforeInitialization方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用bean的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 调用所有的BeanPostProcessor的postProcessAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
通过分析以上代码,我们可以得出初始化过程依次所做的各种操作。
(1)调用各种aware接口方法
a.如果bean是BeanNameAware的实例,则调用它的setBeanName方法
b.如果bean是BeanClassLoaderAware的实例,则调用它的setBeanClassLoader方法
c.如果bean是BeanFactoryAware的实例,则调用它的setBeanFactory方法。
(2)调用所有的BeanPostProcessor对象的postProcessBeforeInitialization方法
获取spring容器中所有的BeanPostProcessor对象,循环执行各个beanPostProcessor的postProcessBeforeInitialization方法,如果出现postProcessBeforeInitialization返回的对象为null,则终止循环,返回上一个postProcessBeforeInitialization方法返回的对象,然后进入第(3)步。
(3)调用bean的初始化方法
a.如果bean是InitializingBean的实例,则调用它的afterPropertiesSet方法
b.如果bean有自定义的初始化方法,则通过反射执行它的自定义初始化方法。
(4)调用所有的BeanPostProcessor的postProcessAfterInitialization方法
获取spring容器中所有的BeanPostProcessor对象,循环执行各个beanPostProcessor的postProcessAfterInitialization方法,如果出现postProcessAfterInitialization返回的对象为null,则终止循环,直接返回上一个postProcessAfterInitialization方法返回的对象。
3、正常使用bean
经过了bean的创建过程,此时就可以正常使用spring容器中的bean了
4、销毁bean
当spring容器被销毁的时候,容器中的bean也随之销毁。而容器被销毁的时候,又会针对各个bean依次作出如下操作:
(1)如果bean中有标记@PreDestroy的方法,则执行该方法
(2)如果bean实现了DisposableBean接口,则调用它的destroy方法
(3)如果Bean有自定义的销毁方法,则执行该方法
结束语
本文先分享到这里,觉得有收获的朋友,可以点击“关注”,或者进行分享或收藏,有疑惑的也可以来私聊评论,我会及时进行回复~
转载自:https://juejin.cn/post/7228977496515199034