【发布时间】:2017-04-06 04:39:42
【问题描述】:
我正在尝试优雅地关闭我的应用程序。因此,当触发应用程序关闭时,我需要让关闭进程等待配置的秒数,在此期间我仍然会服务一些请求。
我一直在尝试在 destroy() 方法中使用等待/睡眠,但此时上下文已经被销毁。我的理解是容器会调用destroy()。是否可以控制销毁方法并延迟关闭过程的启动?
谢谢。
【问题讨论】:
标签: java servlets servletcontextlistener
我正在尝试优雅地关闭我的应用程序。因此,当触发应用程序关闭时,我需要让关闭进程等待配置的秒数,在此期间我仍然会服务一些请求。
我一直在尝试在 destroy() 方法中使用等待/睡眠,但此时上下文已经被销毁。我的理解是容器会调用destroy()。是否可以控制销毁方法并延迟关闭过程的启动?
谢谢。
【问题讨论】:
标签: java servlets servletcontextlistener
你给定的方法不起作用。原因是destroy()方法。每个servlet都有自己的destroy()方法。这些方法在容器卸载servlet时调用,不是在您的应用程序关闭时。当容器将不使用 servlet 时,可以卸载 servlet。您可以让您的应用程序运行,但您的 servlet 仍然可能被容器卸载,因为容器可能已经确定这些 servlet 是不需要。
解决方案:您可能需要一个 ServletContextListener。 ServletContext 与您的整个应用程序相关联,而不仅仅是与单个 servlet 相关联。当你的应用被加载时,ServletContextListener的contextInitialized()被调用,当你的应用被卸载时,contextDestroyed()被调用。所以在contextDestroyed()中,你可以休眠线程并执行其他任务。
@WebListener
public class MyContextListener implements ServletContextListener
{
public void contextInitialized(ServletContextEvent event)
{
System.out.println("\n \n \n \n ServletContext is being initialized..... \n \n \n");
}
//Perform cleanups like removing DB connection.closing session etc. while closing appliction
public void contextDestroyed(ServletContextEvent event)
{
try{
//Sleep this thread.
Thread.sleep(10000);
} catch(Exception ex){ ex.printStackTrace(System.err); }
}
}
【讨论】:
ServletContextListener::contextDestoyed 方法实现中不会实现让 servlet 做更多工作的目标。到那时,Servlet 已经停止了。根据类文档:在任何 ServletContextListener 收到上下文销毁通知之前,所有 servlet 和过滤器都将被销毁。