Em um aplicativo Spring MVC, inicializo uma variável em uma das classes de serviço usando a seguinte abordagem:
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/userLibrary.xml");
service = context.getBean(UserLibrary.class);
A UserLibrary é um utilitário de terceiros que estou usando em meu aplicativo. O código acima gera um aviso para a variável 'contexto'. O aviso é mostrado abaixo:
Resource leak: 'context' is never closed
Eu não entendo o aviso. Como o aplicativo é um aplicativo Spring MVC, não posso realmente fechar / destruir o contexto, pois me refiro ao serviço enquanto o aplicativo está em execução. O que exatamente o aviso está tentando me dizer?
java
eclipse
spring
spring-mvc
ziggy
fonte
fonte
Respostas:
Como o contexto do aplicativo é um
ResourceLoader
(ou seja, operações de E / S), ele consome recursos que precisam ser liberados em algum ponto. É também uma extensão doAbstractApplicationContext
que implementaClosable
. Portanto, ele tem umclose()
método e pode ser usado em uma instrução try-with-resources .Se você realmente precisa criar esse contexto é uma questão diferente (você vinculou a ele), não vou comentar sobre isso.
É verdade que o contexto é fechado implicitamente quando o aplicativo é interrompido, mas isso não é bom o suficiente. O Eclipse está certo, você precisa tomar medidas para fechá-lo manualmente para outros casos, a fim de evitar vazamentos do carregador de classe.
fonte
ApplicationContext
interface de base não forneça oclose()
método,ConfigurableApplicationContext
(queClassPathXmlApplicationContext
implementa) fornece e se estendeCloseable
para inicializar, então você pode usar o paradigma Java 7 try-with-resource.ApplicationContext
e coçando minha cabeça por que estava recebendo o aviso quando não parecia haver um método de fechamento disponível ...close()
não está definido naApplicationContext
interface.A única maneira de se livrar do aviso com segurança é a seguinte
Ou, em Java 7
A diferença básica é que, uma vez que você instancia o contexto explicitamente (ou seja, pelo uso de
new
), você conhece a classe que está instanciando, portanto, pode definir sua variável de acordo.Se você não estivesse instanciando o AppContext (ou seja, usando aquele fornecido pelo Spring), não seria possível fechá-lo.
fonte
new ClassPathXmlApplicationContext(...);
Deve estar fora do bloco de tentativas. Então, não há necessidade de verificação de nulos. Se o construtor lançar uma exceção, entãoctx
será nulo e ofinally
bloco não será chamado (porque a exceção foi lançada fora do bloco try). Se o construtor não lançou uma exceção, otry
bloco é inserido ectx
não pode ser nulo, portanto, não há necessidade de uma verificação de nulo.Um simples elenco resolve o problema:
fonte
Como o contexto do aplicativo possui uma instância de ClassPathXmlApplicationContext e o mesmo possui um método close (). Eu simplesmente faria um CAST do objeto appContext e invocaria o método close () conforme abaixo.
Isso corrigirá o aviso de Vazamento de Recursos.
fonte
tente isso. você precisa aplicar elenco para fechar o contexto do aplicativo.
fonte
Mesmo eu tendo exatamente o mesmo aviso, tudo que fiz foi declarar
ApplicationContext
fora da função principal comoprivate static
e ta-da, problema corrigido.fonte
@SupressWarnings
anotação, mas ainda melhor resolver o problema raiz, não acha?Casting é a resolução correta para este problema. Eu enfrentei o mesmo problema usando a linha abaixo.
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
Para resolver o aviso, apenas abaixe o
ctx
objeto como abaixo e feche-o.((AnnotationConfigApplicationContext) ctx).close();
fonte
Faça downcast do contexto para ConfigurableApplicationContext.
fonte
((ConfigurableApplicationContext)(context)).close();
pode ser esta é a resposta certaNo meu caso, o vazamento desaparece
fonte
Isso funcionou melhor para mim.
fonte
Se você estiver usando ClassPathXmlApplicationContext , poderá usar
para fechar o problema de vazamento de recursos.
Se você estiver usando AbstractApplicationContext , poderá convertê-lo com o método close.
Depende do tipo de contexto usado no aplicativo.
fonte
fonte
Você torna o contexto uma variável estática, o que significa que o contexto está disponível para todos os métodos estáticos da classe, e não mais limitado ao escopo do método principal. Portanto, a ferramenta não pode mais assumir que deve ser fechada no final do método, então ela não emite mais o aviso.
fonte
Sim, a interface
ApplicationContext
não temclose()
método, então eu gosto de usar a classeAbstractApplicationContext
para usar esseclose
método explicitamente e também aqui você pode usar sua classe de configuração do Spring Application usando anotação em vez deXML
tipo.seu
Resource leak: 'context' is never closed
aviso se foi agora.fonte
ele tem uma solução simples, basta inserir o jar do núcleo nas bibliotecas, fornecidas neste link [baixar os arquivos jar do núcleo para a primavera] [1] [1]: https://static.javatpoint.com/src/sp/spcorejars. fecho eclair
fonte
O método close foi adicionado à interface ConfigurableApplicationContext, portanto, o melhor que você pode fazer para obter acesso a ele é:
fonte