Dans une application MVC de printemps, j'initialise une variable dans l'une des classes de service en utilisant l'approche suivante:
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/userLibrary.xml");
service = context.getBean(UserLibrary.class);
L'UserLibrary est un utilitaire tiers que j'utilise dans mon application. Le code ci-dessus génère un avertissement pour la variable «context». L'avertissement est affiché ci-dessous:
Resource leak: 'context' is never closed
Je ne comprends pas l'avertissement. Comme l'application est une application Spring MVC, je ne peux pas vraiment fermer / détruire le contexte car je fais référence au service pendant que l'application est en cours d'exécution. Qu'est-ce que l'avertissement essaie de me dire exactement?
java
eclipse
spring
spring-mvc
ziggy
la source
la source
Réponses:
Étant donné que le contexte de l'application est une
ResourceLoader
(c'est-à-dire des opérations d'E / S), il consomme des ressources qui doivent être libérées à un moment donné. C'est aussi une extensionAbstractApplicationContext
dont implémenteClosable
. Ainsi, il a uneclose()
méthode et peut être utilisé dans une instruction try-with-resources .Que vous ayez réellement besoin de créer ce contexte est une question différente (vous y êtes lié), je ne vais pas commenter cela.
Il est vrai que le contexte est fermé implicitement lorsque l'application est arrêtée mais ce n'est pas suffisant. Eclipse a raison, vous devez prendre des mesures pour le fermer manuellement pour les autres cas afin d'éviter les fuites de classloader.
la source
ApplicationContext
interface de base ne fournit pas laclose()
méthode,ConfigurableApplicationContext
(quiClassPathXmlApplicationContext
implémente) le fait et l'étendCloseable
au démarrage, vous pouvez donc utiliser le paradigme Java 7 try-with-resource.ApplicationContext
et que je me gratte la tête sur pourquoi je recevais l'avertissement alors qu'il ne semblait pas y avoir de méthode proche disponible ...close()
n'est pas défini dans l'ApplicationContext
interface.Le seul moyen de se débarrasser de l'avertissement en toute sécurité est le suivant
Ou, en Java 7
La différence fondamentale est que puisque vous instanciez le contexte explicitement (c'est-à-dire en utilisant
new
) vous connaissez la classe que vous instanciez, vous pouvez donc définir votre variable en conséquence.Si vous n'étiez pas instancié l'AppContext (c'est-à-dire en utilisant celui fourni par Spring), vous ne pouviez pas le fermer.
la source
new ClassPathXmlApplicationContext(...);
doit être en dehors du bloc d'essai. Ensuite, il n'est pas nécessaire de vérifier la valeur nulle. Si le constructeur lève une exception, la valeurctx
est null et lefinally
bloc n'est pas appelé (car l'exception a été levée en dehors du bloc try). Si le constructeur n'a pas lancé d'exception, letry
bloc est entré etctx
ne peut pas être nul, il n'est donc pas nécessaire de vérifier la valeur NULL.Un simple casting résout le problème:
la source
Comme le contexte Application a une instance de ClassPathXmlApplicationContext et le même a une méthode close (). Je voudrais simplement CAST l'objet appContext et invoquer la méthode close () comme ci-dessous.
Cela corrigera l'avertissement de fuite de ressources.
la source
essaye ça. vous devez appliquer le cast pour fermer applicationcontext.
la source
Même j'avais exactement le même avertissement, tout ce que j'ai fait était de déclarer en
ApplicationContext
dehors de la fonction principale commeprivate static
et ta-da, problème résolu.la source
@SupressWarnings
annotation, mais encore mieux pour résoudre le problème racine, vous ne pensez pas?La diffusion est la bonne solution pour ce problème. J'ai rencontré le même problème en utilisant la ligne ci-dessous.
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
Pour résoudre l'avertissement, abattez simplement l'
ctx
objet comme ci-dessous, puis fermez-le.((AnnotationConfigApplicationContext) ctx).close();
la source
Réduisez le contexte en ConfigurableApplicationContext.
la source
((ConfigurableApplicationContext)(context)).close();
c'est peut-être la bonne réponseDans mon cas, la fuite disparaît
la source
Cela a fonctionné le mieux pour moi.
la source
Si vous utilisez le ClassPathXmlApplicationContext, vous pouvez utiliser
pour fermer le problème de fuite de ressources.
Si vous utilisez AbstractApplicationContext, vous pouvez effectuer un cast avec la méthode close.
Cela dépend du type de contexte utilisé dans l'application.
la source
la source
Vous faites du contexte une variable statique, ce qui signifie que le contexte est disponible pour toutes les méthodes statiques de la classe, et n'est plus limité à la portée de la méthode main. Ainsi, l'outil ne peut plus supposer qu'il devrait être fermé à la fin de la méthode, il n'émet donc plus d'avertissement.
la source
Oui, l'interface
ApplicationContext
n'a pas declose()
méthode, donc j'aime utiliser la classeAbstractApplicationContext
pour utiliser cetteclose
méthode explicitement et ici, vous pouvez également utiliser votre classe de configuration Spring Application en utilisant l'annotation au lieu duXML
type.votre
Resource leak: 'context' is never closed
avertissement est parti maintenant.la source
il a une solution simple, il suffit d'entrer le jar Core dans les bibliothèques, donné à ce lien [télécharger les fichiers jar core pour spring] [1] [1]: https://static.javatpoint.com/src/sp/spcorejars. Zip *: français
la source
La méthode close a été ajoutée à l'interface ConfigurableApplicationContext, donc le mieux que vous puissiez faire pour y accéder est:
la source