Spring ApplicationContext - 资源泄漏:“context”永远不会关闭

2022-08-31 10:29:36

在弹簧 MVC 应用程序中,我使用以下方法初始化其中一个服务类中的变量:

ApplicationContext context = 
         new ClassPathXmlApplicationContext("META-INF/userLibrary.xml");
service = context.getBean(UserLibrary.class);

用户库是我在应用程序中使用的第三方实用程序。上面的代码为“上下文”变量生成警告。警告如下所示:

Resource leak: 'context' is never closed

我不明白警告。由于应用程序是Spring MVC应用程序,因此在应用程序运行时,我无法真正关闭/销毁上下文,因为我指的是服务。警告到底想告诉我什么?


答案 1

由于应用程序上下文是ResourceLoader(即I / O操作),因此它消耗的资源需要在某个时候释放。它也是实现 .因此,它有一个方法,可以在try-with-resources语句中使用。AbstractApplicationContextClosableclose()

try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/userLibrary.xml")) {
  service = context.getBean(UserLibrary.class);
}

你是否真的需要创建这个上下文是一个不同的问题(你链接到它),我不打算对此发表评论。

确实,当应用程序停止时,上下文是隐式关闭的,但这还不够好。Eclipse是正确的,您需要采取措施在其他情况下手动关闭它,以避免类加载器泄漏。


答案 2

close()未在接口中定义。ApplicationContext

安全摆脱警告的唯一方法是:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...);
try {
    [...]
} finally {
    ctx.close();
}

或者,在Java 7中

try(ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...)) {
    [...]
}

基本区别在于,由于您显式实例化了上下文(即通过使用 ),因此您知道要实例化的类,因此您可以相应地定义变量。new

如果您没有实例化AppContext(即使用Spring提供的那个),那么您就无法关闭它。


推荐