管理servlet容器中的资源闭包

时间:2010-06-15 02:18:31

标签: java tomcat servlets

我正在使用Tomcat作为servlet容器,并且部署了许多WAR。许多WAR共享公共基类,由于不同的类加载器等,它们在每个上下文中都会被复制。

如何在不挂钩每个web.xml文件以添加上下文侦听器的情况下确保上下文销毁时的资源清理?

理想情况下,我喜欢

的内容
class MyResourceHolder implements SomeListenerInterface {
    private SomeResource resource;
    {
        SomeContextThingie.registerDestructionListener(this);
    }
    public void onDestroy() { resource.close(); }
}

可以在每个web.xml中添加一些东西,但由于可能有很多WAR而且只有实际初始化资源的那些需要清理它,所以在注册清理时似乎更自然资源已初始化,而不是复制大量的XML配置,然后可能清理。

(在这种特殊情况下,我正在启动SQL连接池的有序关闭。但我发现这在许多其他情况下也很有用......)

我确信那里有一些非常明显的解决方案,但我的Google-fu现在让我失望了。谢谢!

3 个答案:

答案 0 :(得分:2)

ServletContextListener之外没有其他可行的选择。

如果您已经使用Servlet 3.0,那么您可以使用@WebListener对其进行注释,并将其与webapp一起发送,它将自动加载。但是对于Servlet 2.5及更早版本,你真的需要对web.xml进行麻烦。

答案 1 :(得分:1)

您可以将资源放在共享类加载器中并将它们作为JNDI资源使用 - 您必须非常小心地通过这样做来保持应用程序同步 - 尽管这是一个选项。

可能取决于您要清理哪种资源,以及您期望在API中看到哪种流失。

注意:类加载器问题可能很难调试 - “类XClass不是XClass的实例”会让你疯狂。

Edit1:另一个选项:您可以在池或其他对象上使用终结器 - 这应该允许您执行代码(例如卸载Web应用程序并回收池时) - 这就是许多JDK类清理本机资源。如果你这样做,要非常小心,因为终结器队列上的死锁将阻止所有类型的重要清理,并可能导致你的JVM崩溃,因为没有使用终结器的东西会得到gc'd。

答案 2 :(得分:0)

将SQL连接池移出Web应用程序并移入Web容器,然后通过JNDI访问它。