Java Web应用程序的关闭挂钩

40

我需要在Java Web应用程序停止或Tomcat停止时保存一些数据。这该怎么做呢? 编辑: 如果我使用JVM关闭挂钩,是否有任何缺点?

4个回答

55

在你的web.xml中使用实现了ServletContextListener接口的类:


<web-app>
    <!-- Usual stuff here -->
    <listener>
        <listener-class>com.mycompany.MyClass</listener-class>
    </listener>
</web-app>

19
现在更加便捷了... Servlet 3.0规范中新增的@WebListener注解可以让您获得此功能,无需编辑web.xml。请参阅BalusC提供的这个启发性答案。 - Basil Bourque

16
为什么你要在关机期间特别执行它?而且你真的需要保存它吗(即“它是绝对必要的吗?”),还是你想要保存它(即“很好但我可以不做”)?
区别很重要-无论您尝试什么方法(如其他答案建议的servlet /上下文侦听器或JVM关闭挂钩),都不能保证它实际上会被调用。
Servlet /上下文侦听器销毁事件只会在正常(有礼貌的)容器关闭或应用程序重新加载期间触发。 JVM关闭挂钩也将在进程中断期间触发; 但是杀死进程(或切断电源)显然不会触发任何操作。

1
它属于“不是必须但没有也能活”的类别。当应用程序关闭时,我需要将我的应用程序尝试连接的一堆服务器状态保存到文件(而不是数据库)中,然后在再次启动应用程序时重新加载这些信息。如果我的应用程序尝试连接到一个宕机的服务器,那么它会将其标记为宕机,以便不必再次重试。由于查询经常发生,因此我只在内存中标记这些状态,而不是在文件中标记。因此,当应用程序关闭时,记住哪些服务器已经宕机会很好。 - user121196
我倾向于使用ServletContextListener或JVM hook。 - user121196
5
不要使用JVM钩子,那更适用于Tomcat本身或桌面应用程序。你应该绝对优先选择使用ServletContextListener而不是JVM钩子。 - Steve McLeod
1
根据您的评论,我会选择ServletContextListener。虽然我不一定同意JVM钩子是“为Tomcat本身而设计的”,但在您的情况下,如果您的上下文被停止(即使Tomcat没有停止),您需要保存数据,因此监听器更合适。 - ChssPly76

12

除了leonm的回答外:

如果你正在使用Spring,你可以使用Spring的“生命周期管理”来实现类似的效果。例如,你可以在一个bean中的方法上注释@PreDestroy,以便在容器关闭时自动调用它。这样,你就不需要把任何东西放到web.xml中。

请参见Spring beans factory lifecycle


3

我建议使用ehcache来缓存这些信息。如果您使用ehcache的持久存储,那么当您再次启动Tomcat时,缓存的数据仍然可用。

实际上,这将问题委托给了ehcache,它针对这些类型的问题进行了优化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接