在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应用程序,因此当我在应用程序运行时引用该服务时,我无法真正关闭/销毁上下文。警告试图告诉我的是什么?
答案 0 :(得分:83)
由于应用程序上下文是ResourceLoader
(即I / O操作),因此它消耗了需要在某个时刻释放的资源。它也是实现AbstractApplicationContext
的{{1}}的扩展。因此,它有一个Closable
方法,可以在try-with-resources statement中使用。
close()
你是否真的需要创建这个上下文是一个不同的问题(你链接到它),我不会对此发表评论。
当应用程序停止时,上下文是隐式关闭的,但这不够好。 Eclipse是对的,您需要采取措施为其他情况手动关闭它,以避免类加载器泄漏。
答案 1 :(得分:38)
close()
未在ApplicationContext
界面中定义。
安全摆脱警告的唯一方法是以下
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...);
try {
[...]
} finally {
ctx.close();
}
或者,在Java 7中
try(ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...)) {
[...]
}
基本区别在于,由于您明确地实例化了上下文(即使用new
),因此您知道要实例化的类,因此您可以相应地定义变量。
如果你没有实例化AppContext(即使用Spring提供的那个),那么就无法关闭它。
答案 2 :(得分:12)
简单的演员解决了这个问题:
((ClassPathXmlApplicationContext) fac).close();
答案 3 :(得分:6)
由于Application上下文具有ClassPathXmlApplicationContext的实例,因此它具有close()方法。我只需要运行appContext对象并调用close()方法,如下所示。
ApplicationContext appContext = new ClassPathXmlApplicationContext("spring.xml");
//do some logic
((ClassPathXmlApplicationContext) appContext).close();
这将修复资源泄漏警告。
答案 4 :(得分:4)
试试这个。你需要应用强制转换来关闭applicationcontext。
ClassPathXmlApplicationContext ctx = null;
try {
ctx = new ClassPathXmlApplicationContext(...);
[...]
} finally {
if (ctx != null)
((AbstractApplicationContext) ctx).close();
}
答案 5 :(得分:3)
即使我有完全相同的警告,我所做的只是在主函数之外声明ApplicationContext
private static
和ta-da,问题已解决。
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();
}
}
答案 6 :(得分:1)
将上下文向下转换为ConfigurableApplicationContext。
((ConfigurableApplicationContext)context).close();
答案 7 :(得分:1)
Object obj = context.getBean("bean");
if(bean instanceof Bean) {
Bean bean = (Bean) obj;
}
在我的情况下,泄漏消失了
答案 8 :(得分:1)
这对我来说效果最好。
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());
}
}
答案 9 :(得分:0)
对于ApplicationContext,您不能使用close()方法,因为该方法未定义int,而是可以使用:(ClassPathXmlApplicationContext(context)).close()
答案 10 :(得分:0)
它有一个简单的解决方案,只需将Core jar输入到此链接中给出的库中 [下载春季的核心jar文件] [1] [1]:https://static.javatpoint.com/src/sp/spcorejars.zip
答案 11 :(得分:0)
铸造是解决此问题的正确方法。
我在下面一行中遇到了同样的问题。
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
要解决该警告,只需将ctx
对象向下投射,如下所示,然后将其关闭。
((AnnotationConfigApplicationContext) ctx).close();
答案 12 :(得分:0)
是的,界面t
没有ApplicationContext
方法,因此我喜欢使用课程close()
明确使用该AbstractApplicationContext
方法,此处您也可以使用使用注释而不是close
类型的Spring Application配置类。
XML
你的AbstractApplicationContext context = new AnnotationConfigApplicationContext(SpringAppConfig.class);
Foo foo = context.getBean(Foo.class);
//do some work with foo
context.close();
警告现在消失了。
答案 13 :(得分:0)
您将上下文设置为静态变量,这意味着上下文可用于类中的所有静态方法,而不再局限于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();
}
}
答案 14 :(得分:0)
import org.springframework.context.ConfigurableApplicationContext;
((ConfigurableApplicationContext)ctx).close();
答案 15 :(得分:0)
如果您使用 ClassPathXmlApplicationContext ,则可以使用
((ClassPathXmlApplicationContext) context).close();
关闭资源泄漏问题。
如果您使用 AbstractApplicationContext ,则可以使用close方法强制转换它。
((AbstractApplicationContext) context).close();
这取决于应用程序中使用的上下文类型。
答案 16 :(得分:-1)
方法关闭已添加到ConfigurableApplicationContext界面,因此您可以做的最好的方法是访问它:
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
"/app-context.xml");
// Use the context...
context.close();