I am new to Spring Framework, while executing below code I am getting a warning "Resource leak: 'context' is never closed"
package com.programmingtechie.examples;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
public class Main {
@SuppressWarnings("deprecation")
public static void main(String[] args){
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
User user = (User)factory.getBean("user");
System.out.println("This Text is using BeanFactory");
System.out.println("My Name is "+user.getName());
System.out.println("My Age is "+user.getAge());
System.out.println("My Height is "+user.getHeight());
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User contextUser = (User)context.getBean("user");
System.out.println("This Text is using ApplicationContext");
System.out.println("My Name is "+contextUser.getName());
System.out.println("My Age is "+contextUser.getAge());
System.out.println("My Height is "+contextUser.getHeight());
// ((ConfigurableApplicationContext) context).close();
}
}
I know that if I uncomment the ((ConfigurableApplicationContext) context).close();
line the warning would be resolved. But I found another way which resolved the warning message here and I don't know the reason for this behaviour. How does the below code resolve the resource leak warning ?
package com.programmingtechie.examples;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
public class Main {
private static ApplicationContext context;
@SuppressWarnings("deprecation")
public static void main(String[] args){
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
User user = (User)factory.getBean("user");
System.out.println("This Text is using BeanFactory");
System.out.println("My Name is "+user.getName());
System.out.println("My Age is "+user.getAge());
System.out.println("My Height is "+user.getHeight());
context = new ClassPathXmlApplicationContext("beans.xml");
User contextUser = (User)context.getBean("user");
System.out.println("This Text is using ApplicationContext");
System.out.println("My Name is "+contextUser.getName());
System.out.println("My Age is "+contextUser.getAge());
System.out.println("My Height is "+contextUser.getHeight());
}
}
In the first case, the scope of the context is limited to the main method. The tool thus assumes that the context is only used by the main method, and should thus be closed at the end of the method.
In the second case, you make the context a static variable, which means that the context is available to all the static methods in the class, and not limited to the scope of the main method anymore. So the tool can't assume that it should be closed at the end of the method anymore, so it doesn't issue the warning anymore.
That doesn't mean the second code is better than the first one, to the contrary. Non-final static variables are a design smell in general. And since the context has no reason to be exposed outside of the main method, it shouldn't be: the smaller the scope of a variable is, the better.