[SPRING] Spring ApplicationContext - 리소스 누출 : 'context'는 절대로 닫히지 않습니다.
SPRINGSpring ApplicationContext - 리소스 누출 : 'context'는 절대로 닫히지 않습니다.
봄 MVC 응용 프로그램에서 다음 방법을 사용하여 서비스 클래스 중 하나에서 변수를 초기화합니다.
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/userLibrary.xml");
service = context.getBean(UserLibrary.class);
UserLibrary는 제 신청서에서 사용하는 타사 유틸리티입니다. 위의 코드는 'context'변수에 대한 경고를 생성합니다. 경고는 아래와 같습니다.
Resource leak: 'context' is never closed
나는 경고를 이해하지 못한다. 응용 프로그램은 Spring MVC 응용 프로그램이므로 응용 프로그램이 실행되는 동안 서비스를 참조 할 때 문맥을 닫거나 닫을 수는 없습니다. 말해 주려고하는 경고가 정확히 무엇입니까?
해결법
-
==============================
1.앱 컨텍스트는 ResourceLoader (예 : I / O 작업)이므로 어느 시점에서 해제해야하는 리소스를 사용합니다. 또한 Closable을 구현하는 AbstractApplicationContext의 확장입니다. 따라서 close () 메서드가있어 try-with-resources 문에서 사용할 수 있습니다.
앱 컨텍스트는 ResourceLoader (예 : I / O 작업)이므로 어느 시점에서 해제해야하는 리소스를 사용합니다. 또한 Closable을 구현하는 AbstractApplicationContext의 확장입니다. 따라서 close () 메서드가있어 try-with-resources 문에서 사용할 수 있습니다.
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/userLibrary.xml")) { service = context.getBean(UserLibrary.class); }
실제로이 컨텍스트를 만들 필요가 있는지 여부는 다른 질문입니다 (연결된 경우). 나는 그것에 대해 언급하지 않을 것입니다.
응용 프로그램이 중지되었지만 충분히 좋지 않을 때 컨텍스트가 암시 적으로 닫히는 것은 사실입니다. 이클립스가 옳다면 클래스 로더 누출을 피하기 위해 다른 경우에 수동으로 닫아야한다.
-
==============================
2.close ()는 ApplicationContext 인터페이스에 정의되어 있지 않습니다.
close ()는 ApplicationContext 인터페이스에 정의되어 있지 않습니다.
경고를 안전하게 제거하는 유일한 방법은 다음과 같습니다.
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...); try { [...] } finally { ctx.close(); }
또는 Java 7
try(ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...)) { [...] }
기본 차이점은 컨텍스트를 명시 적으로 인스턴스화 (즉, new를 사용)함으로써 인스턴스를 생성하는 클래스를 알 수 있으므로 그에 따라 변수를 정의 할 수 있다는 것입니다.
AppContext를 인스턴스화하지 않았다면 (즉, Spring에서 제공 한 인스턴스를 사용하면) 닫을 수 없다.
-
==============================
3.간단한 캐스트는이 문제를 해결합니다.
간단한 캐스트는이 문제를 해결합니다.
((ClassPathXmlApplicationContext) fac).close();
-
==============================
4.응용 프로그램 컨텍스트에는 ClassPathXmlApplicationContext의 인스턴스가 있으며이 인스턴스에는 close () 메서드가 있습니다. appContext 객체를 간단하게 CAST하고 아래와 같이 close () 메서드를 호출합니다.
응용 프로그램 컨텍스트에는 ClassPathXmlApplicationContext의 인스턴스가 있으며이 인스턴스에는 close () 메서드가 있습니다. appContext 객체를 간단하게 CAST하고 아래와 같이 close () 메서드를 호출합니다.
ApplicationContext appContext = new ClassPathXmlApplicationContext("spring.xml"); //do some logic ((ClassPathXmlApplicationContext) appContext).close();
그러면 리소스 누출 경고가 수정됩니다.
-
==============================
5.이 시도. applicationcontext를 닫으려면 캐스트를 적용해야합니다.
이 시도. applicationcontext를 닫으려면 캐스트를 적용해야합니다.
ClassPathXmlApplicationContext ctx = null; try { ctx = new ClassPathXmlApplicationContext(...); [...] } finally { if (ctx != null) ((AbstractApplicationContext) ctx).close(); }
-
==============================
6.심지어 똑같은 경고를 받았다. 내가 한 모든 것은 ApplicationContext를 private static과 ta-da으로 메인 함수 밖에서 선언했기 때문에 문제가 해결되었다.
심지어 똑같은 경고를 받았다. 내가 한 모든 것은 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(); } }
-
==============================
7.Context를 ConfigurableApplicationContext로 다운 캐스트합니다.
Context를 ConfigurableApplicationContext로 다운 캐스트합니다.
((ConfigurableApplicationContext)context).close();
-
==============================
8.
Object obj = context.getBean("bean"); if(bean instanceof Bean) { Bean bean = (Bean) obj; }
내 경우에는 누수가 사라집니다.
-
==============================
9.ClassPathXmlApplicationContext를 사용하는 경우에는 다음을 사용할 수 있습니다.
ClassPathXmlApplicationContext를 사용하는 경우에는 다음을 사용할 수 있습니다.
((ClassPathXmlApplicationContext) context).close();
리소스 누출 문제를 닫습니다.
AbstractApplicationContext를 사용하는 경우 close 메소드를 사용하여이를 캐스팅 할 수 있습니다.
((AbstractApplicationContext) context).close();
응용 프로그램에서 사용하는 컨텍스트 유형에 따라 다릅니다.
-
==============================
10.
import org.springframework.context.ConfigurableApplicationContext; ((ConfigurableApplicationContext)ctx).close();
-
==============================
11.컨텍스트를 정적 변수로 만들면 컨텍스트가 더 이상 main 메서드의 범위에 국한되지 않고 클래스의 모든 정적 메서드에서 사용할 수 있습니다. 따라서 도구는 메소드의 끝에서 더 이상 닫히지 않아야한다고 가정 할 수 없으므로 경고를 더 이상 발행하지 않습니다.
컨텍스트를 정적 변수로 만들면 컨텍스트가 더 이상 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(); } }
-
==============================
12.예, interface ApplicationContext에는 close () 메소드가 없으므로 AbstractApplicationContext 클래스를 사용하여 명시 적으로 close 메소드를 사용하고 XML 유형 대신 annotation을 사용하여 Spring 애플리케이션 구성 클래스를 사용할 수 있습니다.
예, interface ApplicationContext에는 close () 메소드가 없으므로 AbstractApplicationContext 클래스를 사용하여 명시 적으로 close 메소드를 사용하고 XML 유형 대신 annotation을 사용하여 Spring 애플리케이션 구성 클래스를 사용할 수 있습니다.
AbstractApplicationContext context = new AnnotationConfigApplicationContext(SpringAppConfig.class); Foo foo = context.getBean(Foo.class); //do some work with foo context.close();
리소스 누출 : '컨텍스트'가 닫히지 않습니다. 경고가 사라졌습니다.
-
==============================
13.이것은 나를 위해 최선을 다했다.
이것은 나를 위해 최선을 다했다.
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()); } }
-
==============================
14.close 메소드가 ConfigurableApplicationContext 인터페이스에 추가되었으므로 액세스를 얻는 최선의 방법은 다음과 같습니다.
close 메소드가 ConfigurableApplicationContext 인터페이스에 추가되었으므로 액세스를 얻는 최선의 방법은 다음과 같습니다.
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext( "/app-context.xml"); // Use the context... context.close();
from https://stackoverflow.com/questions/14184059/spring-applicationcontext-resource-leak-context-is-never-closed by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 문자열 값의 자리 표시자를 해결할 수 없습니다. (0) | 2019.01.28 |
---|---|
[SPRING] 스프링 데이터 JPA 내장 객체 속성으로 찾기 (0) | 2019.01.28 |
[SPRING] Spring에서 STOMP 및 WebSocket을 사용하여 특정 사용자에게 메시지를 보내는 동안 인증 확인 (0) | 2019.01.28 |
[SPRING] ThreadLocals을 스프링 주입 싱글 톤에 넣어야합니까? (0) | 2019.01.28 |
[SPRING] 포트 80에서 실행중인 Spring Boot 앱 (0) | 2019.01.28 |