스프링 MVC 애플리케이션에서 다음 접근 방식을 사용하여 서비스 클래스 중 하나에서 변수를 초기화합니다.
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/userLibrary.xml");
service = context.getBean(UserLibrary.class);
UserLibrary는 내 응용 프로그램에서 사용중인 타사 유틸리티입니다. 위의 코드는 ‘context’변수에 대한 경고를 생성합니다. 경고는 다음과 같습니다.
Resource leak: 'context' is never closed
경고를 이해하지 못합니다. 애플리케이션이 Spring MVC 애플리케이션이기 때문에 애플리케이션이 실행되는 동안 서비스를 참조 할 때 컨텍스트를 실제로 닫거나 삭제할 수 없습니다. 나에게 알려 주려는 경고가 정확히 무엇입니까?
답변
앱 컨텍스트는 ResourceLoader
(예 : I / O 작업)이므로 어느 시점에서 해제해야하는 리소스를 소비합니다. 또한의 확장 AbstractApplicationContext
구현 Closable
. 따라서 close()
메서드가 있으며 try-with-resources 문 에서 사용할 수 있습니다 .
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/userLibrary.xml")) {
service = context.getBean(UserLibrary.class);
}
이 컨텍스트를 실제로 만들어야하는지 여부는 다른 질문 (연결된 질문 임)에 대해서는 언급하지 않겠습니다.
응용 프로그램이 중지되면 컨텍스트가 암시 적으로 닫히는 것은 사실이지만 충분하지 않습니다. Eclipse가 맞습니다. 클래스 로더 누출을 피하기 위해 다른 경우에 대해 수동으로 닫는 조치를 취해야합니다.
답변
close()
ApplicationContext
인터페이스에 정의되어 있지 않습니다 .
경고를 안전하게 제거하는 유일한 방법은 다음과 같습니다.
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...);
try {
[...]
} finally {
ctx.close();
}
또는 Java 7에서
try(ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...)) {
[...]
}
기본적인 차이점은 컨텍스트를 명시 적으로 (즉을 사용하여 new
) 인스턴스화하므로 인스턴스화하는 클래스를 알고 있으므로 그에 따라 변수를 정의 할 수 있다는 것입니다.
AppContext를 인스턴스화하지 않았다면 (즉, Spring에서 제공하는 것을 사용) 닫을 수 없습니다.
답변
간단한 캐스트가 문제를 해결합니다.
((ClassPathXmlApplicationContext) fac).close();
답변
Application 컨텍스트에는 ClassPathXmlApplicationContext의 인스턴스가 있고 동일한 인스턴스에는 close () 메서드가 있습니다. 간단히 appContext 개체를 CAST하고 아래와 같이 close () 메서드를 호출합니다.
ApplicationContext appContext = new ClassPathXmlApplicationContext("spring.xml");
//do some logic
((ClassPathXmlApplicationContext) appContext).close();
리소스 누출 경고가 수정됩니다.
답변
이 시도. applicationcontext를 닫으려면 캐스트를 적용해야합니다.
ClassPathXmlApplicationContext ctx = null;
try {
ctx = new ClassPathXmlApplicationContext(...);
[...]
} finally {
if (ctx != null)
((AbstractApplicationContext) ctx).close();
}
답변
나는 똑같은 경고를 받았지만 내가 한 모든 것은 문제가 해결 된 ApplicationContext
것과 같이 주요 기능 외부에서 선언 하는 것 private static
뿐입니다.
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();
}
}
답변
전송은이 문제에 대한 올바른 해결 방법입니다. 아래 줄을 사용하여 동일한 문제에 직면했습니다.
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
경고를 해결하려면 ctx
아래와 같이 개체를 한 다음 닫으십시오.
((AnnotationConfigApplicationContext) ctx).close();