我有一个在Tomcat服务器上运行的spring web应用程序。在其中一个Spring bean中有一段代码,它等待数据库连接变得可用。我的场景是,在等待数据库连接时,如果Tomcat关闭,我应该停止等待DB连接并中断循环。
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时它不会被中断。我还试图通过使用spring-bean的销毁方法来实现我的场景,但令我惊讶的是,销毁方法从未被调用过。我的假设是Spring应用程序上下文没有完全构造好--因为我在Spring bean中有上面的等待循环--并且当调用shutdown时,相应的上下文close不会被调用。
有什么建议吗?
发布于 2016-05-27 14:04:59
Tomcat为Web应用程序定义了一个生命周期(嗯,它是一种常见的规范方面,不只是tomcat特有的,而且无论如何……)
所以有一种方法可以连接到这个进程并终止循环或其他任何东西。
在spring中,这非常容易,因为如果tomcat优雅地关闭,tomcat会在实际退出进程之前尝试“取消部署”战争。在servlet规范中,为了做到这一点,可以定义和调用一个特殊的web侦听器(有关更多信息,请参阅javax.servlet.ServletContextListener API )。
现在spring实际上实现了这样一个侦听器,一旦被调用,它就会关闭应用程序上下文。一旦发生这种情况,您的@PreDestroy方法将被自动调用。这已经是一个春天的东西了,tomcat与此无关。
因此,底线是,在bean上指定@PreDestroy方法,该方法将设置一些标志或其他东西,并且它将关闭试图关闭连接的逻辑。
当然,如果只使用kill -9 <tomcat's pid>,上面所述的所有内容都不会真正起作用,但在这种情况下,整个jvm都停止了,所以bean无关紧要。
https://stackoverflow.com/questions/37475371
复制相似问题