Tomcat正常关闭时,如何获得线程中断/通知



我有一个spring web应用程序在Tomcat服务器上运行。在其中一个Springbean中有一段代码,它等待数据库连接可用。我的场景是,在等待数据库连接时,如果Tomcat关闭,我应该停止等待数据库连接并中断循环。

private Connection prepareDBConnectionForBootStrapping()  {
Connection connection = null;
while (connection == null && !Thread.currentThread().isInterrupted()) {
try {
connection = getConnection();
break;
} catch (MetadataServerException me) {
try {
if (!Thread.currentThread().isInterrupted()) {
Thread.sleep(TimeUnit.MINUTES.toMillis(1));
} else {
break;
}
} catch (InterruptedException ie) {
logger.error("Thread {} got interrupted while wating for the database to become available.",
Thread.currentThread().getName());
break;
}
}
}
return connection;
} 

上面的代码段是由Tomcat的一个线程执行的,并且在调用shutdown时不会被中断。我还试图通过使用springbean的destroy方法来实现我的场景,但令我惊讶的是,destroy从未被调用。我的假设是,Spring应用程序上下文没有得到完全构建——因为,我在Spring bean中有上面的等待循环——当调用shutdown时,不会调用相应的上下文close。

有什么建议吗?

Tomcat定义了Web应用程序的生命周期(好吧,这是一种常见的规范方面,不仅仅是Tomcat特定的,而且无论如何…)

因此,有一种方法可以挂接到这个过程并终止循环或其他什么。

在春天,这很容易,因为如果tomcat优雅地关闭,tomcat会在实际退出进程之前尝试"取消部署"WAR。在servlet规范中,为了做到这一点,可以定义并调用一个特殊的web侦听器(有关更多信息,请参阅javax.servlet.ServletContextListenerAPI)

现在spring实际上实现了这样一个监听器,一旦被调用,它就会关闭应用程序上下文。一旦发生这种情况,就会自动调用@PreDestroy方法。这已经是春天的事了,tomcat与此无关。

所以,底线是,在bean上指定@PreDestroy方法,该方法将设置一些标志或其他东西,并关闭试图关闭连接的逻辑。

当然,如果您只使用kill -9 <tomcat's pid>,上述所有内容都不会真正起作用,但在这种情况下,整个jvm都会停止,因此bean无关紧要。

最新更新