Spring 容器的关闭流程

目录

      • AbstractApplicationContext 中的相关源码
        • 关闭容器的2种方式
        • 核心方法 doClose()
        • doClose() 流程图

 

springboot源码版本 2.3.12.RELEASE

AbstractApplicationContext 中的相关源码

关闭容器的2种方式

/**
 * 向jvm注册一个关闭钩子(shutdown hook),在jvm关闭(jvm shutdown)时自动做一些操作
 */
@Override
public void registerShutdownHook() {
	if (this.shutdownHook == null) {
		//定义关闭钩子,jvm关闭时会自动执行这个Thread实例中的run()方法
		this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) 
			@Override
			public void run() {
				//实质是调用 doClose() 进行关闭
				synchronized (startupShutdownMonitor) {
					doClose();
				}
			}
		};
		//向jvm添加关闭钩子
		Runtime.getRuntime().addShutdownHook(this.shutdownHook);
	}
}


/**
 * 销毁容器,实质是调用 close() 关闭容器
 * spring官方不建议使用这个方法,推荐直接用 close() 代替
 */
@Deprecated
public void destroy() {
	close();
}


/**
 * Close this application context, destroying all beans in its bean factory.
 * Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
 * 
 * 关闭容器。
 * 会销毁容器中所有的bean,如果向jvm注册了关闭钩子,也会移除钩子
 */
@Override
public void close() {
	synchronized (this.startupShutdownMonitor) {
		//做一些关闭操作
		doClose();
		// doClose()已经完成了关闭操作,如果有关闭钩子此时可以移除关闭钩子了
		if (this.shutdownHook != null) {
			try {
				Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
			}
			catch (IllegalStateException ex) {
				// ignore - VM is already shutting down
			}
		}
	}
}

关闭容器有2种方式

  • 启动时向jvm注册一个关闭钩子,jvm终止时自动回调关闭钩子中指定的 doClose() 方法关闭容器
  • 直接调用 close() 或将过时的 destroy() 方法关闭容器,实质也是调用 doClose() 关闭容器

不管哪种关闭方式,关闭容器的核心方法都是 doClose()

 

核心方法 doClose()

/**
 * 关闭应用上下文
 */
protected void doClose() {
	//检查上下文是否处于激活状态
	if (this.active.get() && this.closed.compareAndSet(false, true)) {
		if (logger.isDebugEnabled()) {
			logger.debug("Closing " + this);
		}

		//移除应用上下文的注册
		LiveBeansView.unregisterApplicationContext(this);

		//发布上下文已关闭事件 ContextClosedEvent
		try {
			publishEvent(new ContextClosedEvent(this));
		}
		catch (Throwable ex) {
			logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
		}

		//调用生命周期管理器的 onClose() 方法,终止对容器中各个bean的生命周期管理
		if (this.lifecycleProcessor != null) {
			try {
				this.lifecycleProcessor.onClose();
			}
			catch (Throwable ex) {
				logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
			}
		}

		//销毁容器中所有的(单例)bean
		//这里的容器指的是高级容器内嵌的低级容器 beanFactory,bean都是放在内置的beanFactory中的
		destroyBeans();

		//关闭内置的beanFactory
		closeBeanFactory();

		//预留的扩展点,在关闭beanFactory后做一些额外操作
		onClose();

		//重置存储监听器的2个成员变量
		if (this.earlyApplicationListeners != null) {
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		//设置上下文的激活状态为false
		this.active.set(false);
	}
}


/**
 * 销毁容器中所有的(单例)bean。
 * 如果bean实现了 DisposableBean 接口,或使用 destroy-method 属性指定了销毁方法,会调用对应的销毁方法
 */
protected void destroyBeans() {
	getBeanFactory().destroySingletons();
}


/**
 * 预留给子类的扩展点,可以在内置的beanFactory关闭后做一些自定义处理
 */
protected void onClose() {
	// For subclasses: do nothing by default.
}

 

doClose() 流程图

Spring 容器的关闭流程_第1张图片

你可能感兴趣的:(Spring,spring,容器关闭流程,close,doClose)