В приложении 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, я не могу закрыть / уничтожить контекст, поскольку я обращаюсь к службе во время работы приложения. Что именно пытается мне сказать предупреждение?
java
eclipse
spring
spring-mvc
зигги
источник
источник
Ответы:
Поскольку контекст приложения - это
ResourceLoader
(то есть операции ввода-вывода), он потребляет ресурсы, которые необходимо освободить в какой-то момент. Это тоже продолжениеAbstractApplicationContext
орудияClosable
. Таким образом, у него естьclose()
метод, и его можно использовать в операторе try-with-resources .try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/userLibrary.xml")) { service = context.getBean(UserLibrary.class); }
Действительно ли вам нужно создать этот контекст - это другой вопрос (вы связались с ним), я не буду это комментировать.
Верно, что контекст закрывается неявно, когда приложение останавливается, но этого недостаточно. Eclipse прав, вам нужно принять меры, чтобы закрыть его вручную для других случаев, чтобы избежать утечек загрузчика классов.
источник
ApplicationContext
Стоит отметить: хотя базовый интерфейс не предоставляетclose()
метод,ConfigurableApplicationContext
(которыйClassPathXmlApplicationContext
реализует) поддерживаетCloseable
загрузку и расширяется до нее , поэтому вы можете использовать парадигму попытки с ресурсами в Java 7.ApplicationContext
и ломал голову над тем, почему я получал предупреждение, когда, похоже, не было доступного метода закрытия ...close()
не определен вApplicationContext
интерфейсе.Единственный способ безопасно избавиться от предупреждения - это
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...); try { [...] } finally { ctx.close(); }
Или в Java 7
try(ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...)) { [...] }
Основное отличие состоит в том, что, поскольку вы создаете экземпляр контекста явно (т. Е. С помощью
new
), вы знаете класс, который создаете, поэтому вы можете определить свою переменную соответствующим образом.Если вы не создавали экземпляр AppContext (т.е. использовали тот, который предоставлен Spring), вы не могли бы его закрыть.
источник
new ClassPathXmlApplicationContext(...);
Должно быть за пределами блока попытки. Тогда нет необходимости в нулевой проверке. Если конструктор выдает исключение, онctx
имеет значение null, иfinally
блок не вызывается (поскольку исключение было создано за пределами блока try). Если конструктор не сгенерировал исключение, тогдаtry
блок вводится иctx
не может быть нулевым, поэтому нет необходимости в нулевой проверке.Простое приведение решает проблему:
источник
Поскольку у контекста приложения есть экземпляр ClassPathXmlApplicationContext, и он же имеет метод close (). Я бы просто CAST объект appContext и вызвал метод close (), как показано ниже.
ApplicationContext appContext = new ClassPathXmlApplicationContext("spring.xml"); //do some logic ((ClassPathXmlApplicationContext) appContext).close();
Это устранит предупреждение об утечке ресурсов.
источник
попробуй это. вам нужно применить приведение, чтобы закрыть контекст приложения.
ClassPathXmlApplicationContext ctx = null; try { ctx = new ClassPathXmlApplicationContext(...); [...] } finally { if (ctx != null) ((AbstractApplicationContext) ctx).close(); }
источник
Даже у меня было точно такое же предупреждение, все, что я сделал, это объявил
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(); } }
источник
@SupressWarnings
аннотацией, но все же лучше решить корневую проблему, не так ли?Кастинг - правильное решение этой проблемы. Я столкнулся с той же проблемой, используя строку ниже.
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
Чтобы устранить предупреждение, просто опустите
ctx
объект, как показано ниже, а затем закройте его.((AnnotationConfigApplicationContext) ctx).close();
источник
Понизьте контекст до ConfigurableApplicationContext.
источник
((ConfigurableApplicationContext)(context)).close();
может быть, это правильный ответObject obj = context.getBean("bean"); if(bean instanceof Bean) { Bean bean = (Bean) obj; }
В моем случае утечка исчезает
источник
Это сработало лучше всего для меня.
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()); } }
источник
Если вы используете ClassPathXmlApplicationContext, вы можете использовать
чтобы закрыть проблему утечки ресурсов.
Если вы используете AbstractApplicationContext, вы можете применить его с помощью метода close.
Это зависит от типа контекста, используемого в приложении.
источник
import org.springframework.context.ConfigurableApplicationContext; ((ConfigurableApplicationContext)ctx).close();
источник
Вы делаете контекст статической переменной, что означает, что контекст доступен для всех статических методов в классе и больше не ограничивается областью действия основного метода. Таким образом, инструмент больше не может предполагать, что он должен быть закрыт в конце метода, поэтому он больше не выдает предупреждение.
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(); } }
источник
Да, у интерфейса
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();
ваше
Resource leak: 'context' is never closed
предупреждение исчезло.источник
у него есть простое решение: просто введите Core jar в библиотеки, указанные по этой ссылке [загрузите файлы core jar для spring] [1] [1]: https://static.javatpoint.com/src/sp/spcorejars. застегивать
источник
Метод close был добавлен в интерфейс ConfigurableApplicationContext, поэтому лучшее, что вы можете сделать, чтобы получить к нему доступ:
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext( "/app-context.xml"); // Use the context... context.close();
источник