java - Spring ApplicationContext - 资源泄漏:'context'永远不会关闭
在spring MVC应用程序中,我使用以下方法初始化其中一个服务类中的变量:
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/userLibrary.xml");
service = context.getBean(UserLibrary.class);
UserLibrary是我在我的应用程序中使用的第三方实用程序。 上面的代码为'context'变量生成警告。 警告如下所示:
Resource leak: 'context' is never closed
我不明白这个警告。 由于应用程序是一个Spring MVC应用程序,因此当我在应用程序运行时引用该服务时,我无法真正关闭/销毁上下文。 试图告诉我的警告究竟是什么?
15个解决方案
83 votes
由于应用程序上下文是AbstractApplicationContext(即I / O操作),因此它消耗了在某些时候需要释放的资源。 它也是AbstractApplicationContext的扩展,它实现了Closable.因此,它有一个close()方法,可以在try-with-resources语句中使用。
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/userLibrary.xml")) {
service = context.getBean(UserLibrary.class);
}
你是否真的需要创建这个上下文是一个不同的问题(你链接到它),我不会对此发表评论。
确实,当应用程序停止时,上下文会被隐式关闭,但这不够好。 Eclipse是对的,您需要采取措施为其他情况手动关闭它,以避免类加载器泄漏。
Marcel Stör answered 2019-09-04T04:05:21Z
38 votes
new未在ApplicationContext接口中定义。
安全摆脱警告的唯一方法如下
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...);
try {
[...]
} finally {
ctx.close();
}
或者,在Java 7中
try(ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...)) {
[...]
}
基本区别在于,由于您明确地实例化了上下文(即使用new),因此您知道要实例化的类,因此您可以相应地定义变量。
如果您没有实例化AppContext(即使用Spring提供的那个),那么您无法关闭它。
usr-local-ΕΨΗΕΛΩΝ answered 2019-09-04T04:06:11Z
11 votes
一个简单的演员解决了这个问题:
((ClassPathXmlApplicationContext) fac).close();
RCInd answered 2019-09-04T04:06:36Z
6 votes
由于Application上下文具有ClassPathXmlApplicationContext的实例,因此它具有close()方法。 我只需要CAST appContext对象并调用close()方法,如下所示。
ApplicationContext appContext = new ClassPathXmlApplicationContext("spring.xml");
//do some logic
((ClassPathXmlApplicationContext) appContext).close();
这将修复资源泄漏警告。
Ashutosh Srivastav answered 2019-09-04T04:07:06Z
4 votes
试试这个。 你需要应用强制转换来关闭applicationcontext。
ClassPathXmlApplicationContext ctx = null;
try {
ctx = new ClassPathXmlApplicationContext(...);
[...]
} finally {
if (ctx != null)
((AbstractApplicationContext) ctx).close();
}
madhu_karnati answered 2019-09-04T04:07:31Z
3 votes
即使我有完全相同的警告,我所做的只是在主函数private static和ta-da之外声明ApplicationContext,问题已修复。
public class MainApp {
private static ApplicationContext context;
public static void main(String[] args) {
context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
objA.setMessage("I'm object A");
objA.getMessage();
HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
objB.getMessage();
}
}
Elysium answered 2019-09-04T04:07:56Z
1 votes
将上下文向下转换为ConfigurableApplicationContext。
((ConfigurableApplicationContext)context).close();
amit28 answered 2019-09-04T04:08:21Z
1 votes
Object obj = context.getBean("bean");
if(bean instanceof Bean) {
Bean bean = (Bean) obj;
}
在我的情况下泄漏消失
леонид павлов answered 2019-09-04T04:08:46Z
1 votes
这对我来说最好。
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
private static ApplicationContext con;
public static void main(String[] args) {
con = new ClassPathXmlApplicationContext("config.xml");
Employee ob = (Employee) con.getBean("obj");
System.out.println("Emp Id " + ob.getEmpno());
System.out.println("Emp name " + ob.getEmpname());
}
}
i4nk1t answered 2019-09-04T04:09:11Z
0 votes
如果您使用的是ClassPathXmlApplicationContext,则可以使用
((ClassPathXmlApplicationContext) context).close();
关闭资源泄漏问题。
如果您正在使用AbstractApplicationContext,则可以使用close方法强制转换它。
((AbstractApplicationContext) context).close();
它取决于应用程序中使用的上下文类型。
Laxman Edara answered 2019-09-04T04:09:55Z
0 votes
import org.springframework.context.ConfigurableApplicationContext;
((ConfigurableApplicationContext)ctx).close();
Yao Pan answered 2019-09-04T04:10:14Z
0 votes
您将上下文设置为静态变量,这意味着上下文可用于类中的所有静态方法,而不再局限于main方法的范围。 因此,该工具不能假定它应该在方法结束时关闭,因此它不再发出警告。
public class MainApp {
private static ApplicationContext context;
public static void main(String[] args) {
context =
new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
}
}
Nanhe Kumar answered 2019-09-04T04:10:39Z
0 votes
是的,接口Resource leak: 'context' is never closed没有close()方法,所以我喜欢使用类AbstractApplicationContext明确地使用该close方法,并且在这里您可以使用注释而不是XML类型来使用Spring Application配置类。
AbstractApplicationContext context = new AnnotationConfigApplicationContext(SpringAppConfig.class);
Foo foo = context.getBean(Foo.class);
//do some work with foo
context.close();
你的Resource leak: 'context' is never closed警告现在消失了。
ArifMustafa answered 2019-09-04T04:11:12Z
0 votes
转换是此问题的正确解决方案。我使用下面的代码遇到了同样的问题。ctx
要解决警告,只需向下传输ctx对象,然后关闭它。((AnnotationConfigApplicationContext) ctx).close();
Aadi answered 2019-09-04T04:11:46Z
-1 votes
close方法已添加到ConfigurableApplicationContext接口,因此您可以做的最好的方法是访问它:
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
"/app-context.xml");
// Use the context...
context.close();
Carlos Curotto answered 2019-09-04T04:12:14Z
9706

被折叠的 条评论
为什么被折叠?



