概述
目录
- 1. 前言
- 1.1. 回顾 `doCreateBean()` 方法
- 2. `registerDisposableBeanIfNecessary()` 方法概览
- 2.1. `requiresDestruction()` 方法重点
- 2.1.1. 检查是否有 `DestructionAwareBeanPostProcessor` 实现类
- 3. `registerDisposableBeanIfNecessary()` 方法小结
- 4. `Spring` 注册关闭钩子 `ShutdownHook`
- 4.1. `registerShutdownHook()` 方法
- 4.2. `destroyBeans()` 方法
- 4.3. `destroySingletons()` 方法
- 4.4. `destroySingletons()` 方法
- 4.5. `destroy()` 方法
- 5. 小结
- 5.1. 给 `bean` 设置销毁方法的方式
- 5.2. 什么样的 `bean` 才能销毁
1. 前言
这篇文章是 IOC
容器初始化启动时,抽象类 AbstractAutowireCapableBeanFactory
的 doCreateBean()
方法里面的 registerDisposableBeanIfNecessary()
方法,它是进行 bean
的销毁的方法
阅读本篇文章,同时可以参考阅读 spring源码之getBean(获取 bean)方法解读(二) 和 Spring Aop代理对象的产生(一) 这两篇文章的 doCreateBean()
方法
1.1. 回顾 doCreateBean()
方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// BeanWrapper封装了具体的Bean实例,然后可以很方便地通过调用getPropertyValue和setPropertyValue等方法反射读写Bean的具体属性
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 先尝试从缓存中取
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 调用构造方法创建一个空实例对象,并用BeanWrapper进行包装
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 获取所有的后置处理器,如果后置处理器实现了MergedBeanDefinitionPostProcessor接口,则一次调用其postProcessMergedBeanDefinition方法
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 如果满足循环依赖缓存条件,先缓存具体对象
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
/**
* 循环依赖处理逻辑:将已完成实例化,但是未完成属性赋值和相关的初始化的一个不完整的 bean 添加到三级缓存 singletonFactories 中
* 具体内部会遍历后置处理器,判断是否有SmartInstantiationAwareBeanPostProcessor的实现类,然后调用里面getEarlyBeanReference覆盖当前Bean
* 默认不做任何操作返回当前Bean,作为拓展,这里比如可以供AOP来创建代理类
*/
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 开始对Bean实例进行初始化
Object exposedObject = bean;
try {
// 对bean进行属性填充,在这里面完成依赖注入的相关内容
populateBean(beanName, mbd, instanceWrapper);
// 完成属性依赖注入后,进一步初始化Bean
// 具体进行了以下操作:
// 1.若实现了BeanNameAware, BeanClassLoaderAware,BeanFactoryAwareAware等接口,则注入相关对象
// 2.遍历后置处理器,调用实现的postProcessBeforeInitialization方法,
// 3.如果实现了initialzingBean,调用实现的 afterPropertiesSet()
// 4.如果配置了init-mothod,调用相应的init方法
// 5.遍历后置处理器,调用实现的postProcessAfterInitialization
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);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// 如果实现了Disposable接口,会在这里进行注册,最后在销毁的时候调用相应的destroy方法
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
doCreateBean(beanName, mbd, args)
的主要方法流程:(重点)
createBeanInstance(beanName, mbd, args)
:实例化bean
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
:将已完成实例化,但是未完成属性赋值和相关的初始化的一个不完整的bean
添加到三级缓存singletonFactories
中populateBean(beanName, mbd, instanceWrapper)
:对bean
进行属性填充注入initializeBean(beanName, exposedObject, mbd)
:完成bean
的属性填充注入后,进一步初始化bean
,在此过程中产生代理对象。此时bean
的创建工作正式完成,已经可以在项目中使用了registerDisposableBeanIfNecessary(beanName, bean, mbd)
:如果符合bean
的销毁条件,则执行单例bean
的销毁工作
2. registerDisposableBeanIfNecessary()
方法概览
它的具体调用是在 AbstractBeanFactory
中的 registerDisposableBeanIfNecessary()
方法
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
// 当前 bean 的作用域不是 Prototype && requiresDestruction 返回 true
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
// bean 的作用域是单例的
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
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));
}
}
}
2.1. requiresDestruction()
方法重点
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean.getClass() != NullBean.class &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}
可以看到 requiresDestruction()
方法只要满足下面任意一个即可
hasDestroyMethod()
:检查给定bean
是否有任何类型的destroy
销毁的方法可调用hasApplicableProcessors()
:检查是否有DestructionAwareBeanPostProcessor
的实现类,并且requiresDestruction()
方法返回true
2.1.1. 检查是否有 DestructionAwareBeanPostProcessor
实现类
- 实现了
ApplicationListener
接口 - 方法加上了
@PreDestroy
注解
3. registerDisposableBeanIfNecessary()
方法小结
- 当
bean
的作用域不是Prototype
,同时给bean
设置了销毁方法或有DestructionAwareBeanPostProcessor
实现类 - 在满足了上述条件之后,如果
bean
的作用域是单例的时,创建DisposableBeanAdapter
进行注册(添加到disposableBeans
集合LinkedHashMap
中)
// DefaultSingletonBeanRegistry 的属性
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
4. Spring
注册关闭钩子 ShutdownHook
spring
会先去调用注册的关闭钩子 ShutdownHook
,通过这个方式进行销毁前的动作处理
public SpringApplicationBuilder registerShutdownHook(boolean registerShutdownHook) {
this.registerShutdownHookApplied = true;
this.application.setRegisterShutdownHook(registerShutdownHook);
return this;
}
4.1. registerShutdownHook()
方法
该方法在 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);
}
}
4.2. destroyBeans()
方法
AbstractApplicationContext
类的 destroyBeans()
方法
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
4.3. destroySingletons()
方法
DefaultListableBeanFactory
类中的 destroySingletons()
方法
@Override
public void destroySingletons() {
super.destroySingletons();
this.manualSingletonNames.clear();
clearByTypeCache();
}
4.4. 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
(前面添加到了disposableBeans
中)
// DefaultSingletonBeanRegistry 的属性
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
- 遍历每个
bean
执行销毁方法 - 取出
bean
的依赖方,先销毁依赖方(就是之前bean
装配提到的@DependsOn
标志的依赖方) - 执行
bean
的destroy
销毁方法,包括下面4
项- 调用
DestructionAwareBeanPostProcessor
来执行销毁方法 - 执行
DisposableBean
的destroy
方法 - 执行
init-method
指定的destroy
方法 - 执行
@Bean
属性指定的destroy
方法
- 调用
- 销毁内部类对象
- 从依赖关系中去掉自己
4.5. destroy()
方法
DisposableBeanAdapter
的 destroy()
方法
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
// 调用DestructionAwareBeanPostProcessor来执行销毁方法,就是上文提到的
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 {
// 执行DisposableBean#destroy方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((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);
}
}
}
// 执行destroy-method指定的销毁方法
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod();
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
5. 小结
5.1. 给 bean
设置销毁方法的方式
- 通过
xml
文件配置destroy-method
标签属性指定的destroy
方法 - 通过注解
@Bean
可以使用属性指定销毁的方法 - 实现
DisposableBean
接口 - 销毁方法名为接口情况下,有
close
或者shutdown
方法
5.2. 什么样的 bean
才能销毁
bean
的作用域是单例时- 给
bean
设置了销毁方法或有DestructionAwareBeanPostProcessor
实现类时
最后
以上就是高高小蘑菇为你收集整理的Spring源码之bean的销毁registerDisposableBeanIfNecessary方法解读1. 前言2. registerDisposableBeanIfNecessary() 方法概览3. registerDisposableBeanIfNecessary() 方法小结4. Spring 注册关闭钩子 ShutdownHook5. 小结的全部内容,希望文章能够帮你解决Spring源码之bean的销毁registerDisposableBeanIfNecessary方法解读1. 前言2. registerDisposableBeanIfNecessary() 方法概览3. registerDisposableBeanIfNecessary() 方法小结4. Spring 注册关闭钩子 ShutdownHook5. 小结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复