In einer Spring-MVC-Anwendung initialisiere ich eine Variable in einer der Serviceklassen mit dem folgenden Ansatz:
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/userLibrary.xml");
service = context.getBean(UserLibrary.class);
Die UserLibrary ist ein Dienstprogramm eines Drittanbieters, das ich in meiner Anwendung verwende. Der obige Code generiert eine Warnung für die 'Kontext'-Variable. Die Warnung wird unten angezeigt:
Resource leak: 'context' is never closed
Ich verstehe die Warnung nicht. Da es sich bei der Anwendung um eine Spring MVC-Anwendung handelt, kann ich den Kontext nicht wirklich schließen / zerstören, da ich auf den Dienst verweise, während die Anwendung ausgeführt wird. Was genau versucht die Warnung mir zu sagen?
java
eclipse
spring
spring-mvc
zickig
quelle
quelle
Antworten:
Da es sich bei dem App-Kontext um einen
ResourceLoader
(dh E / A-Vorgang) handelt, werden Ressourcen verbraucht, die irgendwann freigegeben werden müssen. Es ist auch eine Erweiterung,AbstractApplicationContext
die implementiertClosable
. Daher hat es eineclose()
Methode und kann in einer Try-with-Resources-Anweisung verwendet werden .Ob Sie diesen Kontext tatsächlich erstellen müssen, ist eine andere Frage (Sie haben ihn verlinkt). Ich werde das nicht kommentieren.
Es ist wahr, dass der Kontext implizit geschlossen wird, wenn die Anwendung gestoppt wird, aber das ist nicht gut genug. Eclipse ist richtig, Sie müssen Maßnahmen ergreifen, um es in anderen Fällen manuell zu schließen, um Klassenladerlecks zu vermeiden.
quelle
ApplicationContext
nicht dieclose()
Methode bereitstelltConfigurableApplicationContext
(dieClassPathXmlApplicationContext
implementiert) undCloseable
zum Booten erweitert, können Sie das Java 7-Paradigma für den Versuch mit Ressourcen verwenden.ApplicationContext
und mir den Kopf kratzte, warum ich die Warnung erhielt, als es keine nahe Methode zuclose()
ist nicht in derApplicationContext
Schnittstelle definiert .Die einzige Möglichkeit, die Warnung sicher zu entfernen, ist die folgende
Oder in Java 7
Der grundlegende Unterschied besteht darin, dass Sie, da Sie den Kontext explizit (dh mithilfe von
new
) instanziieren, die Klasse kennen, die Sie instanziieren, sodass Sie Ihre Variable entsprechend definieren können.Wenn Sie den AppContext nicht instanziiert haben (dh den von Spring bereitgestellten verwenden), konnten Sie ihn nicht schließen.
quelle
new ClassPathXmlApplicationContext(...);
muss außerhalb des Versuchsblocks sein. Dann ist die Nullprüfung nicht erforderlich. Wenn der Konstruktor eine Ausnahme auslöst,ctx
ist er null und derfinally
Block wird nicht aufgerufen (da die Ausnahme außerhalb des try-Blocks ausgelöst wurde). Wenn der Konstruktor keine Ausnahme ausgelöst hat, wird dertry
Block eingegeben undctx
kann nicht null sein. Daher ist keine Nullprüfung erforderlich.Eine einfache Besetzung löst das Problem:
quelle
Da der Anwendungskontext eine Instanz von ClassPathXmlApplicationContext und dieselbe eine close () -Methode hat. Ich würde einfach das appContext-Objekt CAST und die close () -Methode wie folgt aufrufen.
Dadurch wird die Warnung "Ressourcenleck" behoben.
quelle
Versuche dies. Sie müssen cast anwenden, um den Anwendungskontext zu schließen.
quelle
Selbst wenn ich genau die gleiche Warnung hatte, war alles, was ich tat,
ApplicationContext
außerhalb der Hauptfunktion alsprivate static
und ta-da zu deklarieren , Problem behoben.quelle
@SupressWarnings
Anmerkung tun , aber immer noch besser, um das Grundproblem zu lösen, finden Sie nicht?Casting ist die richtige Lösung für dieses Problem. Ich hatte das gleiche Problem mit der folgenden Zeile.
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
Um die Warnung zu beheben, werfen Sie das
ctx
Objekt wie unten beschrieben herunter und schließen Sie es dann.((AnnotationConfigApplicationContext) ctx).close();
quelle
Den Kontext auf ConfigurableApplicationContext übertragen.
quelle
((ConfigurableApplicationContext)(context)).close();
Vielleicht ist dies die richtige AntwortIn meinem Fall verschwindet das Leck
quelle
Das hat für mich am besten geklappt.
quelle
Wenn Sie den ClassPathXmlApplicationContext verwenden , können Sie ihn verwenden
um das Problem mit dem Ressourcenleck zu schließen.
Wenn Sie den AbstractApplicationContext verwenden , können Sie diesen mit der close-Methode umwandeln.
Dies hängt von der Art des Kontexts ab, der in der Anwendung verwendet wird.
quelle
quelle
Sie machen den Kontext zu einer statischen Variablen. Dies bedeutet, dass der Kontext allen statischen Methoden in der Klasse zur Verfügung steht und nicht mehr auf den Umfang der Hauptmethode beschränkt ist. Das Tool kann daher nicht mehr davon ausgehen, dass es am Ende der Methode geschlossen werden sollte, sodass die Warnung nicht mehr ausgegeben wird.
quelle
Ja, die Schnittstelle
ApplicationContext
hat keineclose()
Methode, daher verwende ich gerne die KlasseAbstractApplicationContext
, um dieseclose
Methode explizit zu verwenden. Auch hier können Sie Ihre Spring Application-Konfigurationsklasse mithilfe von Anmerkungen anstelle vonXML
Typ verwenden.Ihre
Resource leak: 'context' is never closed
Warnung ist jetzt weg.quelle
Es gibt eine einfache Lösung, bei der Sie einfach das Core-JAR in die Bibliotheken eingeben, die Sie unter diesem Link erhalten [Laden Sie die Core-JAR-Dateien für das Frühjahr herunter] [1] [1]: https://static.javatpoint.com/src/sp/spcorejars. Postleitzahl
quelle
Die Methode close wurde der ConfigurableApplicationContext-Schnittstelle hinzugefügt. Das Beste, was Sie tun können, um Zugriff darauf zu erhalten, ist:
quelle