Spring 作为当前 Java 最流行、最强大的轻量级框架,受到了程序员的青睐。准确的了解 Spring Bean 的生命周期是非常必要的,Spring Bean 的生命周期是 Spring 面试热点问题,想要答好并不容易!本文将从源码的角度入手,帮助小伙伴彻底掌握 Spring Bean 的生命周期。
而 Spring Bean 的生命周期只有 4 个阶段:
主要逻辑都在 doCreateBean 方法(AbstractAutowireCapableBeanFactory类中,逻辑很清晰,就是顺序调用以下三个方法,这三个方法与三个生命周期阶段一一对应,非常重要,在后续扩展接口分析中也会涉及。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//实例化bean
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
//属性赋值
populateBean(beanName, mbd, instanceWrapper);
//初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
exposedObject = earlySingletonReference;
}
}
//销毁前的准备,注册待销毁的 Bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
至于销毁,是在容器关闭时调用的,详见 ConfigurableApplicationContext#close() 方法。
// 创建单例 bean 实例
if (mbd.isSingleton()) { //单例作用域
// 第二个参数是一个ObjectFactory,是一个函数式接口,当调用ObjectFactory的getObject()方法的时候,实际上调用的是createBean(beanName, mbd, args)
// 也就是说在getSingleton()方法内部调用ObjectFactory的getObject()方法的时候,会回调到这里的createBean(beanName, mbd, args)创建bean,接着才会调用下面的getObjectForBeanInstance()方法
// 8、第八步:尝试从缓存中获取对应的bean实例,获取不到的话,则执行singletonFactory的回调 -> createBean()创建bean
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建bean对象
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
// 创建失败则销毁
destroySingleton(beanName);
throw ex;
}
});
// 返回beanName对应的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
从上面的代码中,我们重点分析的是 AbstractBeanFactory#createBean() 方法,而 createBean() 方法的处理流程如下:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//省略部分代码
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
//正式进入生命周期
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
这里我们需要注意在调用 doCreateBean() 之前,调用了resolveBeforeInstantiation() 方法。
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// beforeInstantiationResolved: bean是否已解析的状态标识
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// 1、如果bean不是合成的,并且工厂拥有将在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置增强器
// mbd.isSynthetic()方法的作用:返回这个 bean 定义是否是“合成的”,即不是由应用程序本身定义的
// hasInstantiationAwareBeanPostProcessors()方法的作用:返回此工厂是否拥有将在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 2、确定给定 bean 定义的目标类型,主要是针对含有FactoryMethod的Bean进行特殊处理
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 3、执行InstantiationAwareBeanPostProcessor的前置增强方法:postProcessBeforeInstantiation()
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 4、执行InstantiationAwareBeanPostProcessor的后置增强方法:postProcessAfterInitialization()
// 这里需要注意的是:在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])方法
// 中,在执行doCreateBean()方法前有个判断,如果bean不为空,则会直接返回,所以需要在这里执行bean的后置增强。
// 普通创建bean的后置增强方法:其实是在doCreateBean()方法里面执行的
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
// 5、如果bean不为空,beforeInstantiationResolved标志位设置为true,表示当前bean在实例化前已经解析过
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
当 resolveBeforeInstantiation 返回不为 null 的 bean 后,createBean 会直接返回。也就是说,后续的实例化、属性赋值与初始化阶段都不会进行。这一步,将会给 BeanPostProcessor 一个返回代理而不是目前 bean 的机会。
resolveBeforeInstantiation 核心的方法如下:
在实例化之前执行 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation() 方法,该方法可以返回 bean 实例的代理,从而跳过 Spring 默认的实例化过程。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
//获取到工厂中注册的所有 BeanPostProcessor 后置增强器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断是否是 InstantiationAwareBeanPostProcessor类型
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//如果类型匹配的话,就直接强转了
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//这里执行 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation() 方法
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
//如果 result 不为空,说明存在后置处理器返回了 bean 实例对象,则会跳过 doCreateBean() 的实例化过程
if (result != null) {
return result;
}
}
}
return null;
}
如果经过 postProcessBeforeInstantiation() 方法返回的 bean 不为空,还需要在这里执行 applyBeanPostProcessorsAfterInitialization() 后置增强。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//获取到工厂中注册的所有 BeanPostProcessor 后置增强器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//执行 BeanPostProcessor 的后置增强方法 postProcessAfterInitialization()
Object current = processor.postProcessAfterInitialization(result, beanName);
//如果 postProcessAfterInitialization() 返回为空,则直接返回,将不会执行后续的 BeanPostProcessor 后置处理器的增强
if (current == null) {
return result;
}
//使用增强后的 bean current,赋值给 result,然后返回
result = current;
}
return result;
}
首先尝试从未完成创建的缓存 actoryBeanInstanceCache 中获取 BeanWrapper,如果缓存中不存在的话,则会调用createBeanInstance 创建一个 BeanWrapper。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//将 bean 转化为 class 对象
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//如果 bean 的 class 类型不为空,bean 不是 public 修饰的,且 bean 不允许访问非公共构造函数和方法,那么 Spring 会抛出异常
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());
}
//如果存在用于创建 bean 实例的回调,则从给定的 Supplier 接口获取一个 bean 实例
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//如果存在工厂方法的话,即设置了 factory-method ,则使用工厂方法进行实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
//标识构造函数和工厂方法是否已经被解析过
boolean resolved = false;
//是否需要自动注入
boolean autowireNecessary = false;
//实例化 bean 的参数为空
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//resolvedConstructorOrFactoryMethod 其实是一个缓存,存放已经解析过的构造函数和工厂方法,防止重复解析
if (mbd.resolvedConstructorOrFactoryMethod != null) {
//如果缓存不为空,则修改 resolved 为 true,标记为已解析
resolved = true;
//是否需要自动注入的值取决于 mbd 的 constructorArgumentsResolved 属性
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//如果构造函数和工厂方法已经被解析过,直接使用前面介绍的缓存 resolvedConstructorOrFactoryMethod 里面解析好的,如果需要自动注入,
//则执行构造函数自动注入,否则使用默认构造函数进行实例化
if (resolved) {
if (autowireNecessary) {
//如果需要自动注入,则执行构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
} else {
//如果不需要自动注入,则使用默认构造函数进行实例化
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
//传入 beanClass 和 beanName,通过 SmartInstantiationAwareBeanPostProcessor 的 determineCandidateConstructors() 方法,确定用于给定 bean 的候选构造函数
//因为一个类可以有多个构造方法,每个构造方法都有不同的参数,所以需要根据参数以及类型去判断最终调用哪一个构造方法并进行实例化
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//满足下面四个条件的其中一个,都会执行构造函数的自动注入:
//determineConstructorsFromBeanPostProcessors() 方法返回的构造方法不为空;
//bean 的注入类型为 AUTOWIRE_CONSTRUCTOR;
//存在 bean 定义的构造函数参数值;
//用于构造函数或工厂方法调用的显式参数不为空;
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//执行构造函数的自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
//如果存在用于默认构造的首选构造函数,则执行构造函数的自动注入
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, null);
}
//如果既不存在工厂方法,也不存在带有参数的构造方法,则使用默认的构造方法进行bean的实例化
return instantiateBean(beanName, mbd);
}
这里就不深入探讨了,有兴趣的小伙伴可以进入内部的几种方式看一下。
在实例化结束后,将进入属性赋值阶段,对 bean 各个属性值进行注入,可能存在依赖于其它 bean 的属性,则会递归初始化依赖的 bean。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//针对 bean 的包装器是否为空
//是否存在为此 bean 定义的属性值,做不同的处理
if (bw == null) {
//如果 bean 的包装器为空,但是又存在为此 bean 定义的属性值,Spring 则会抛出 BeanCreationException 异常
// 因为属性填充就是要给 BeanWrapper 中的 bean 实例中的属性进行赋值的过程,存在属性,但是 BeanWrapper 为空,也就是 BeanWrapper 中的 bean 实例为空,那么显然不行
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
} else {
//如果没有为此 bean 定义的属性值,即没有可填充的属性,则直接返回
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// InstantiationAwareBeanPostProcessor后置处理器:可以在属性设置前修改bean
//如果 bean 定义不是合成的,并且工厂中存在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor 后置处理器,则需要处理执行它的 postProcessAfterInstantiation() 方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//获取到 bean 工厂所有已经注册的 BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断是否属于 InstantiationAwareBeanPostProcessor 类型
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//如果类型匹配的话,将会执行 InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation() 方法
//postProcessAfterInstantiation() 方法:在 bean 实例化后,属性填充之前被调用,允许修改 bean 的属性,默认实现是返回 true
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
//如果postProcessAfterInstantiation() 方法返回 false,则跳过后面的属性填充过程
return;
}
}
}
}
//获取到 bean 定义中封装好的属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//根据设置的自动注入方式(名称或者类型)获取属性 bean(递归getBean)存入 PropertyValues 中
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;
}
// hasInstAwareBpps:工厂是否存在将在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// needsDepCheck:是否需要进行依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
//如果存在 InstantiationAwareBeanPostProcessor 后置处理器,需要执行 InstantiationAwareBeanPostProcessor 的postProcessProperties() 以及 postProcessPropertyValues() 方法回调
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//执行 InstantiationAwareBeanPostProcessor 的 postProcessProperties() 以及postProcessPropertyValues() 方法回调
//postProcessProperties(): 允许对填充前的属性进行处理(如对属性的验证)
//postProcessPropertyValues(): 对属性值进行修改,通过基于原始的 PropertyValues 创建一个新的MutablePropertyValues 实例,添加或删除特定的值。
//不过目前方法已经被标记为过期,在后续 Spring 版本中可能会被删除
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;
}
}
}
//执行依赖检查,对应 depend-on 属性
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//依赖检查,对应 depend-on 属性
checkDependencies(beanName, mbd, filteredPds, pvs);
}
//属性填充的具体过程,即将属性值赋值到 beanWrapper 中 bean 实例的具体属性中
if (pvs != null) {
//开始填充属性值
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
代码到这里,实例化与属性赋值阶段结束,我们整理一下其中的扩展点
从 doCreateBean 内的 initializeBean 开始,主要完成如执行 aware 接口、执行 init-method 方法、BeanPostProcessor 后置增强等工作。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//执行Aware方法,如 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
invokeAwareMethods(beanName, bean);
}
//调用 BeanPostProcessor 的前置处理
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//执行 BeanPostProcessor 后置处理器的前置处理方法:postProcessBeforeInitialization(),允许对bean实例进行包装
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//执行初始化方法,包括 InitializingBean 的 afterPropertiesSet() 方法、自定义的初始化方法 init-method
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(),允许对 bean 实例进行包装
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
执行 Aware 方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware。
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
//如果 bean 实现了 BeanNameAware 接口,则设置 BeanName
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
//如果 bean 实现了 BeanClassLoaderAware 接口,则设置 BeanClassLoader
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
//如果 bean 实现了 BeanFactoryAware 接口,则设置 BeanFactory
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
从上面代码中我们知道,只要 Bean 实现了指定的 Aware 接口,Spring 就会向 Bean 注入这些 Aware 相关信息。
执行 BeanPostProcessor 后置处理器的前置处理方法。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//获取所有的 BeanPostProcessor 进行遍历
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//执行每一个 BeanPostProcessor 的前置增强方法:postProcessBeforeInitialization()
Object current = processor.postProcessBeforeInitialization(result, beanName);
//如果 postProcessBeforeInitialization() 返回为空,则直接返回,将不会执行后续的 BeanPostProcessor 后置处理器的增强
if (current == null) {
return result;
}
result = current;
}
return result;
}
执行初始化方法,包括 InitializingBean 的 afterPropertiesSet() 方法、自定义的初始化方法 init-method
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//检查 bean 是否实现了 InitializingBean 接口,如果实现了,则需要执行 InitializingBean 接口的 afterPropertiesSet() 方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
//调用 InitializingBean 接口的 afterPropertiesSet() 方法
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
//直接调用 InitializingBean 接口中的 afterPropertiesSet 方法
((InitializingBean) bean).afterPropertiesSet();
}
}
//调用xml 中声明的 init-method 指定的方法
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
//判断是否指定了 init-method 方法,如果指定了 init-method 方法,则再调用制定的 init-method
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//进入该方法可知通过反射的方式调用 init-method 方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
和前置处理类似,只是调用 postProcessAfterInitialization 方法,不再详述。
因此,初始化过程又可以被细分为:
最后我们看 doCreateBean 方法的 registerDisposableBeanIfNecessary(beanName, bean, mbd)这一句,完成了创建 Bean 的最后一件事情,注册需要执行销毁方法的 Bean。
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
//如果 Bean 不是多例且需要在容器关闭时销毁
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
// 如果 bean 的作用域是 singleton,则会注册用于销毁的 bean 到 disposableBeans 缓存,执行给定 bean 的所有销毁工作
if (mbd.isSingleton()) {
//给当前Bean绑定一个DisposableBeanAdapter
registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
} else {
// 如果 bean 的作用域不是 prototype,也不是 singleton,而是其他作自定义用域的话,则注册一个回调,以在销毁作用域内的指定对象时执行
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
public void registerDisposableBean(String beanName, DisposableBean bean) {
// 注册用于销毁的 bean 到 disposableBeans 的 map 中,以供后续使用
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
什么样的 bean 才能销毁?
spring 会先去调用注册的关闭钩子 ShutdownHook,通过这个方式进行销毁前的动作处理
public SpringApplicationBuilder registerShutdownHook(boolean registerShutdownHook) {
this.registerShutdownHookApplied = true;
this.application.setRegisterShutdownHook(registerShutdownHook);
return this;
}
该方法在 AbstractApplicationContext 类中
@Override
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// No shutdown hook registered yet.
this.shutdownHook = new Thread() {
@Override
public void run() {
synchronized (startupShutdownMonitor) {
// 方法调用如下
doClose();
}
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
protected void doClose() {
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isInfoEnabled()) {
logger.info("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
// Publish shutdown event.
// 发布上下文关闭事件ContextClosedEvent
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
// 调用Lifecycle#stop方法
try {
getLifecycleProcessor().onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
// Destroy all cached singletons in the context's BeanFactory.
// 销毁bean
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
this.active.set(false);
}
}
这里我们选择 destroyBeans() 方法跳进去看
AbstractApplicationContext 类的 destroyBeans() 方法
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
点击 destroySingletons()方法再跳进去看
DefaultListableBeanFactory 类中的 destroySingletons() 方法
@Override
public void destroySingletons() {
super.destroySingletons();
this.manualSingletonNames.clear();
clearByTypeCache();
}
点击 destroySingletons() 方法再跳进去看
DefaultSingletonBeanRegistry 类中的 destroySingletons() 方法
public void destroySingletons() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
// 方法调用如下
destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
this.earlySingletonObjects.clear();
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
}
}
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
// 方法调用如下
destroyBean(beanName, disposableBean);
}
protected void destroyBean(String beanName, DisposableBean bean) {
// Trigger destruction of dependent beans first...
Set<String> dependencies = this.dependentBeanMap.remove(beanName);
if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
if (bean != null) {
try {
// 调用 DisposableBeanAdapter 的 destroy()
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
// Trigger destruction of contained beans...
Set<String> containedBeans = this.containedBeanMap.remove(beanName);
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
}
// Remove destroyed bean from other beans' dependencies.
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.
this.dependenciesForBeanMap.remove(beanName);
}
一直往下走,找到 bean.destroy();这句核心的。点击进去看一下
public void destroy() {
//调用被 @PreDestroy 注解修饰的方法
//具体可以跟进 InitDestroyAnnotationBeanPostProcessor 类
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
//如果实现了 DisposableBean 接口,则调用 destroy 方法
if (this.invokeDisposableBean) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
} else {
((DisposableBean) this.bean).destroy();
}
}
//调用的 destroy-method属性指定的初始化方法
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
} else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod(this.destroyMethodName);
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
到这里,Bean 的销毁过程基本就结束了,下面我们再来概括一下:
以下是 Spring Bean 的完整生命周期从创建 Spring 容器开始,直到最终 Spring 容器销毁 Bean的流程:
这里我们代码验证一下:
public class Student implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {
private String name;
private int phone;
private BeanFactory beanFactory;
private String beanName;
public Student () {
System.out.println("【构造器】调用 Student 的构造器实例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("注入属性 name");
this.name = name;
}
public int getPhone() {
return phone;
}
public void setPhone(int phone) {
System.out.println("注入属性 phone");
this.phone = phone;
}
@Override
public String toString() {
return "Person [name=" + name + ", phone="
+ phone + "]";
}
// 这是 BeanFactoryAware 接口方法
@Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out
.println("调用BeanFactoryAware.setBeanFactory()");
this.beanFactory = arg0;
}
// 这是 BeanNameAware 接口方法
@Override
public void setBeanName(String arg0) {
System.out.println("调用BeanNameAware.setBeanName()");
this.beanName = arg0;
}
// 这是 InitializingBean 接口方法
@Override
public void afterPropertiesSet() throws Exception {
System.out
.println("调用InitializingBean.afterPropertiesSet()");
}
// 这是 DiposibleBean 接口方法
@Override
public void destroy() throws Exception {
System.out.println("调用 DiposibleBean.destory()"); }
// 通过的 init-method 属性指定的初始化方法
public void myInit() {
System.out.println("调用的 init-method 属性指定的初始化方法" );
}
// 通过的 destroy-method 属性指定的初始化方法
public void myDestory() {
System.out.println("调用的 destroy-method 属性指定的初始化方法" );
}
}
public class BeanPostProcessorImpl implements BeanPostProcessor {
public BeanPostProcessorImpl () {
super();
System.out.println("这是 BeanPostProcessor 实现类构造器!!");
}
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
System.out
.println("BeanPostProcessor 接口方法 postProcessAfterInitialization 对属性进行更改!");
return arg0;
}
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out
.println("BeanPostProcessor 接口方法 postProcessBeforeInitialization 对属性进行更改!");
return arg0;
}
BeanPostProcessor 接口包括 2 个方法 postProcessAfterInitialization 和 postProcessBeforeInitialization,这两个方法的第一个参数都是要处理的 Bean 对象,第二个参数都是 Bean 的 name。返回值也都是要处理的 Bean 对象。这里要注意。
public class InstantiationAwareBeanPostProcessorImpl extends
InstantiationAwareBeanPostProcessorAdapter {
public InstantiationAwareBeanPostProcessorImpl () {
super();
System.out
.println("这是 InstantiationAwareBeanPostProcessorAdapter 实现类构造器!!");
}
// 接口方法、实例化 Bean 之前调用
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor 调用 postProcessBeforeInstantiation 方法");
return null;
}
// 接口方法、实例化 Bean 之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor 调用postProcessAfterInitialization 方法");
return bean;
}
// 接口方法、设置某个属性时调用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor 调用 postProcessPropertyValues 方法");
return pvs;
}
}
这个有 3 个方法,其中第二个方法 postProcessAfterInitialization 就是重写了 BeanPostProcessor 的方法。第三个方法postProcessPropertyValues 用来操作属性,返回值也应该是 PropertyValues 对象。
public class BeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public BeanFactoryPostProcessor () {
super();
System.out.println("这是 BeanFactoryPostProcessor 实现类构造器!!");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
throws BeansException {
System.out
.println("BeanFactoryPostProcessor 调用 postProcessBeanFactory 方法");
BeanDefinition bd = arg0.getBeanDefinition("person");
bd.getPropertyValues().addPropertyValue("phone", "110");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="beanPostProcessor" class="test.BeanPostProcessorImpl ">
</bean>
<bean id="instantiationAwareBeanPostProcessor" class="test.InstantiationAwareBeanPostProcessorImpl">
</bean>
<bean id="beanFactoryPostProcessor" class="test.BeanFactoryPostProcessor ">
</bean>
<bean id="student" class=test.Student" init-method="myInit"
destroy-method="myDestory" scope="singleton" p:name="张三" p:phone="18813634567" />
</beans>
下面我们测试一下:
public static void main(String[] args) {
System.out.println("现在开始初始化容器");
ApplicationContext factory = new ClassPathXmlApplicationContext("springBeanTest/beans.xml");
System.out.println("容器初始化成功");
//得到Student,并使用
Person student = factory.getBean("student",Student.class);
System.out.println(student );
System.out.println("现在开始关闭容器!");
((ClassPathXmlApplicationContext)factory).registerShutdownHook();
}
得到的结果为:
现在开始初始化容器
2022-01-17 15:46:20 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@19a0c7c: startup date [Sun May 18 15:46:20 CST 2014]; root of context hierarchy
2022-01-17 15:46:20 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [springBeanTest/beans.xml]
这是 BeanFactoryPostProcessor 实现类构造器!!
BeanFactoryPostProcessor 调用 postProcessBeanFactory 方法
这是 BeanPostProcessor 实现类构造器!!
这是 InstantiationAwareBeanPostProcessorAdapter 实现类构造器!!
2022-01-17 15:46:20 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@9934d4: defining beans [beanPostProcessor,instantiationAwareBeanPostProcessor,beanFactoryPostProcessor,student]; root of factory hierarchy
InstantiationAwareBeanPostProcessor 调用 postProcessBeforeInstantiation 方法
调用Student的构造器实例化
InstantiationAwareBeanPostProcessor 调用 postProcessPropertyValues 方法
注入属性 name
注入属性 phone
调用BeanNameAware.setBeanName()
调用BeanFactoryAware.setBeanFactory()
BeanPostProcessor 接口方法 postProcessBeforeInitialization 对属性进行更改!
调用InitializingBean.afterPropertiesSet()
调用<bean>的 init-method 属性指定的初始化方法
BeanPostProcessor 接口方法 postProcessAfterInitialization 对属性进行更改!
InstantiationAwareBeanPostProcessor 调用 postProcessAfterInitialization 方法
容器初始化成功
Student[name=张三, phone=18813634567]
现在开始关闭容器!
调用 DiposibleBean.destory()
调用<bean>的 destroy-method 属性指定的初始化方法