spring源码注册需要销毁的bean registerDisposableBeanIfNecessary

21 篇文章 1 订阅
11 篇文章 0 订阅
本文探讨了Spring中bean的销毁过程,包括为何需要销毁bean,如何注册需要销毁的bean,以及在什么时机进行销毁。当容器关闭时,会执行bean的销毁方法,包括执行DestructionAwareBeanPostProcessors、DisposableBean接口的destroy方法或自定义的销毁逻辑。此外,还详细阐述了关闭容器的流程,如发布关闭事件、停止生命周期bean等。
摘要由CSDN通过智能技术生成

前篇文章传送门
咱们上篇了解bean的初始化,

大家可以想下,bean为什么要销毁?

  1. 用完不再使用的bean
  2. 指定了destroy方法的bean执行destroy方法
  3. 容器关闭
  4. spring把需要销毁的bean注册到哪里呢?disposableBeans = new LinkedHashMap<>();
  5. 在何时进行销毁的?
registerDisposableBeanIfNecessary 注册需要被销毁的bean
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
	AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
	if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
		if (mbd.isSingleton()) {
			// Register a DisposableBean implementation that performs all destruction
			// work for the given bean: DestructionAwareBeanPostProcessors,
			// DisposableBean interface, custom destroy method.
			// 注册需要被销毁的bean,如果满足 DestructionAwareBeanPostProcessors、实现了DisposableBean或者自定义销毁方法
			registerDisposableBean(beanName,new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
		}
		else {
			// A bean with a custom scope...
			// 这里需要自定义销毁 比如spring给咱们提供好了示例 MyTestScope
			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));
		}
	}
}
requiresDestruction(bean, mbd) 判断是否必须要销毁

满足包含销毁方法或者是DestructionAwareBeanPostProcessors

protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
		return (bean.getClass() != NullBean.class &&
				(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors())))
				);
	}
applicationContext.close(); 销毁

当容器关闭的时候会执行doClose()方法,然后执行destroyBeans(),然后再调用destroySingletons,最后把缓存中(Map)的bean进行移除掉

public void close() {
	synchronized (this.startupShutdownMonitor) {
		//当执行销毁容器时执行
		doClose();
		if (this.shutdownHook != null) {
			try {
				// 这里就是把后台线程给关闭了
				Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
			}catch (IllegalStateException ex) {
				// ignore - VM is already shutting down
			}
		}
	}
}
protected void doClose() {
	// 设置关闭状态
	if (this.active.get() && this.closed.compareAndSet(false, true)) {
		LiveBeansView.unregisterApplicationContext(this);
		try {
			// 关闭事件
			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.
		if (this.lifecycleProcessor != null) {
			try {
				this.lifecycleProcessor.onClose();
			}catch (Throwable ex) {
				logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
			}
		}
		// 先进行执行销毁的方法
		destroyBeans();
		// 在关闭beanFactory 就是无引用关系
		closeBeanFactory();
		// 自定义扩展
		onClose();
		// 清空监听器
		if (this.earlyApplicationListeners != null) {
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}
		// 设置启动状态为关闭
		this.active.set(false);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值