https://blog.youkuaiyun.com/heroqiang/article/details/81541208
版权声明:本文为博主原创文章,转载请注明出处。 https://blog.youkuaiyun.com/heroqiang/article/details/81541208 </div>
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-3019150162.css">
<div id="content_views" class="markdown_views prism-atom-one-light">
<!-- flowchart 箭头图标 勿删 -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<h3><a name="t0"></a><a id="_0"></a>阅读须知</h3>
- Spring源码版本:4.3.8
- 文章中使用/* */注释的方法会做深入分析
正文
我们来看几个销毁bean的场景,在一些异常情况,例如Spring上下文初始化失败时,会销毁已经创建的单例bean,这时会调用相关销毁方法,在Spring容器关闭时,同样会调用disposableBeans的销毁方法:
AbstractApplicationContext:
public void registerShutdownHook() {
if (this.shutdownHook == null) {
this.shutdownHook = new Thread() {
@Override
public void run() {
synchronized (startupShutdownMonitor) {
/* 关闭容器 */
doClose();
}
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
AbstractApplicationContext:
public void close() {
synchronized (this.startupShutdownMonitor) {
/* 关闭容器 */
doClose();
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
在容器注册的关闭钩子的关闭方法中都调用了doClose方法,我们来分析这个方法:
protected void doClose() {
// 判断active激活标记(在初始化上下文时被设置为true用于标记激活状态)并且将closed标记设置为true
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isInfoEnabled()) {
logger.info("Closing " + this);
}
// 卸载注册的JMX的MBean
LiveBeansView.unregisterApplicationContext(this);
try {
// 发布容器关闭事件
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
try {
// 调用实现了Lifecycle的bean的stop方法,关于Lifecycle,我们在标签解析的文章中分析过
getLifecycleProcessor().onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
/* 销毁bean */
destroyBeans();
// 关闭BeanFactory,将BeanFactory序列化id和本身置为null
closeBeanFactory();
// 子类扩展
onClose();
// 将激活标记置为false
this.active.set(false);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
AbstractApplicationContext:
protected void destroyBeans() {
// 销毁单例bean
getBeanFactory().destroySingletons();
}
- 1
- 2
- 3
- 4
DefaultListableBeanFactory:
public void destroySingletons() {
/* 调用父类的销毁方法销毁单例bean */
super.destroySingletons();
// 清空手工注册的beanName的缓存
this.manualSingletonNames.clear();
// 清空类型-->beanName的映射缓存
clearByTypeCache();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
DefaultSingletonBeanRegistry:
public void destroySingletons() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
// 设置正在销毁的标记为true
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
/* 遍历销毁之前注册的所有disposableBean */
destroySingleton(disposableBeanNames[i]);
}
// 清空beanName --> 它包含的所有内部beanName集合的映射缓存
this.containedBeanMap.clear();
// 清空beanName --> 它依赖的所有beanName集合的映射缓存
this.dependentBeanMap.clear();
// 清空beanName --> 依赖它的所有beanName集合的映射缓存
this.dependenciesForBeanMap.clear();
synchronized (this.singletonObjects) {
// 清空单例bean缓存
this.singletonObjects.clear();
// 清空单例工厂缓存
this.singletonFactories.clear();
// 清空提前暴露的beanName --> bean的映射缓存
this.earlySingletonObjects.clear();
// 清空已经注册的单例bean缓存
this.registeredSingletons.clear();
// 设置正在销毁的标记为false
this.singletonsCurrentlyInDestruction = false;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
DefaultSingletonBeanRegistry:
public void destroySingleton(String beanName) {
// 清除bean的相应缓存
removeSingleton(beanName);
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
// 移除并获取disposableBean
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
/* 销毁 */
destroyBean(beanName, disposableBean);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
DefaultSingletonBeanRegistry:
protected void destroyBean(String beanName, DisposableBean bean) {
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) {
// 首选递归销毁所有当前bean依赖的bean
destroySingleton(dependentBeanName);
}
}
if (bean != null) {
try {
// 调用destory方法
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
Set<String> containedBeans = this.containedBeanMap.remove(beanName);
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
// 递归销毁当前bean包含的所有内部bean
destroySingleton(containedBeanName);
}
}
synchronized (this.dependentBeanMap) {
// 遍历找出所有依赖当前bean的列表,将当前bean从被依赖的列表中移除
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();
}
}
}
// 从所有依赖当前bean的映射中移除依赖关系
this.dependenciesForBeanMap.remove(beanName);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
整个Spring销毁bean的流程到这里就结束了。
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-e44c3c0e64.css" rel="stylesheet">
</div>