Sollte der Logger als statisch deklariert werden oder nicht? Normalerweise habe ich zwei Arten von Deklarationen für einen Logger gesehen:
protected Log log = neuer Log4JLogger (aClass.class);
oder
privates statisches Protokoll log = neuer Log4JLogger (aClass.class);
Welches sollte verwendet werden? Was sind die Vor- und Nachteile von beiden?
static
ist eine Referenz pro Klasse. Nicht statisch ist eine Referenz pro Instanz (+ Initialisierung). In einigen Fällen hat letzteres erhebliche Auswirkungen auf den Speicher, wenn Sie Tonnen von Instanzen haben. Verwenden Sie das Nicht-Statische niemals in einem häufigen Objekt. Ich benutze immer die statische Version. (was in Großbuchstaben geschrieben werden sollteLOG
)private static final Log log
Kleinbuchstaben sein. Der Logger ist keine Konstante, der Logger ist ein statisches Endobjekt (das mutiert werden kann). Persönlich benutze ich immerlogger
.Antworten:
Der Vorteil des nicht statischen Formulars besteht darin, dass Sie es in einer (abstrakten) Basisklasse wie folgt deklarieren können, ohne sich Sorgen machen zu müssen, dass der richtige Klassenname verwendet wird:
Der Nachteil ist jedoch offensichtlich, dass für jede Instanz der Klasse eine ganz neue Logger-Instanz erstellt wird. Dies ist zwar an sich nicht teuer, verursacht jedoch einen erheblichen Overhead. Wenn Sie dies vermeiden möchten, möchten Sie
static
stattdessen das Formular verwenden. Der Nachteil ist jedoch, dass Sie es in jeder einzelnen Klasse deklarieren und in jeder Klasse darauf achten müssen, dass der richtige Klassenname während der Erstellung des Loggers verwendet wird, da ergetClass()
nicht im statischen Kontext verwendet werden kann. In der durchschnittlichen IDE können Sie jedoch eine Vorlage für die automatische Vervollständigung erstellen. ZBlogger
+ctrl+space
.Wenn Sie den Logger hingegen von einer Factory beziehen, die wiederum die bereits instanziierten Logger zwischenspeichern kann, führt die Verwendung des nicht statischen Formulars nicht zu einem so hohen Overhead. Log4j hat zum Beispiel eine
LogManager
für diesen Zweck.quelle
abstract Log getLogger();
In der abstrakten Klasse deklarieren . Implementieren Sie diese Methode und geben Sie den statischen Logger für die jeweilige Instanz zurück. Fügen Sieprivate final static Log LOG = LogManager.getLogger(Clazz.class);
Ihrer IDE-Klassenvorlage hinzu.protected Logger log = LoggerFactory.getLogger(getClass());
Früher dachte ich, dass alle Logger statisch sein sollten. aber dieser Artikel bei wiki.apache.org jedoch einige wichtige Speicherprobleme in Bezug auf Classloader-Lecks . Wenn Sie einen Logger als statisch deklarieren, wird verhindert, dass die deklarierende Klasse (und die zugehörigen Klassenladeprogramme) in J2EE-Containern, die einen gemeinsam genutzten Klassenladeprogramm verwenden, als Müll gesammelt werden. Dies führt zu PermGen-Fehlern, wenn Sie Ihre Anwendung genügend oft erneut bereitstellen.
Ich sehe keine Möglichkeit, dieses Problem mit dem Classloader-Leck zu umgehen, außer Logger als nicht statisch zu deklarieren.
quelle
Der wichtigste Unterschied besteht darin, wie sich dies auf Ihre Protokolldateien auswirkt: In welche Kategorie fallen Protokolle?
Es gibt eine Variante Ihres ersten Falls:
protected Log log = neuer Log4JLogger (getClass ());
In diesem Fall gibt Ihre Protokollkategorie an, an welchem Objekt der protokollierte Code gearbeitet hat.
Bei Ihrer zweiten Wahl (private statische) ist die Protokollkategorie die Klasse, die den Protokollierungscode enthält. Normalerweise also die Klasse, die das tut, was protokolliert wird.
Ich würde diese letzte Option wärmstens empfehlen. Es hat diese Vorteile im Vergleich zu den anderen Lösungen:
Es hat auch Nachteile:
quelle
Verwenden Sie die Umkehrung der Steuerung und übergeben Sie den Logger an den Konstruktor. Wenn Sie den Logger innerhalb der Klasse erstellen, werden Sie mit Ihren Unit-Tests eine teuflische Zeit haben. Sie schreiben Unit-Tests, nicht wahr?
quelle