Ihr Kommentar besagt, dass "ausführlich" sich auf die Notwendigkeit bezieht, diese Codezeile in jeder Klasse zu wiederholen. Meine erste Antwort ist, dass das Hinzufügen von zwei Codezeilen (Variablendefinition plus Importanweisung) zu jeder Klasse im Großen und Ganzen keine so große Sache ist. Zumal Sie sie nur zu den Klassen hinzufügen müssen, die Verhalten haben und daher die Protokollierung durchführen müssen. Die von Ihnen verwendete Codezeile ist jedoch anfällig für Fehler beim Kopieren und Einfügen (dazu später mehr).
Da Sie jedoch Alternativen wünschen, sind hier einige aufgeführt, mit Gründen, aus denen Sie diese möglicherweise verwenden möchten oder nicht.
Verwenden Sie einen einzelnen Logger für die gesamte App
Wenn Sie sich nicht darum kümmern, welche Klasse Bericht erstattet, oder bereit sind, den gesamten erforderlichen Kontext in die Nachricht einzufügen, erledigt ein einfacher Singleton-Logger die Aufgabe:
LoggerSingleton.getInstance().debug("MyController is running")
Meiner Meinung nach besteht einer der großen Vorteile eines Protokollierungsframeworks darin, dass der Kontext von separaten Protokollierungsinstanzen bereitgestellt wird - schon allein, um die Protokollnachrichten an verschiedene Ziele zu leiten. Ich würde das nicht aufgeben, nur um eine Codezeile zu speichern (Sie benötigen noch den Import).
Außerdem erhöht dies die Ausführlichkeit am Verwendungsort, was zu weitaus mehr Tastenanschlägen führt.
Erstellen Sie Ihre Logger am Verwendungsort
Ich werfe dieses raus, nur weil es die Variable eliminiert. Ich glaube nicht, dass ich das kommentieren muss. Obwohl es meine bevorzugte Technik zum Abrufen einer Logger-Instanz zeigt.
Logger.getLogger(getClass()).debug("blah blah blah");
Verwenden Sie einen Bean-Postprozessor, um den Logger zu injizieren
In Ihrem Beispiel wird Spring verwendet, und mit Spring können Sie sich in den Bean-Initialisierungscode einbinden. Sie können einen Postprozessor erstellen, der die Bean auf eine logger
Mitgliedsvariable überprüft und eine Logger
Instanz erstellt, wenn sie eine findet.
Während ein solcher Postprozessor nur aus ein paar Dutzend Codezeilen besteht, ist er ein weiterer bewegender Teil Ihrer Anwendung und daher eine weitere potenzielle Fehlerquelle. Ich bevorzuge es, so wenig wie möglich davon zu haben.
Verwenden Sie ein Mixin
Scala und Groovy bieten Eigenschaften , mit denen Sie das Verhalten zusammenfassen können. Ein typisches Scala-Muster besteht darin, ein Logging
Merkmal zu erstellen und es dann der Klasse hinzuzufügen, die protokolliert werden muss:
class MyController with Logging
Dies bedeutet leider, dass Sie die Sprache wechseln müssen. Sofern Sie nicht Java 8 verwenden, können Sie in diesem Fall eine Logging
Schnittstelle mit einer "Standardmethode" erstellen :
public interface Logging {
default Logger getLogger() {
return Logger.getLogger(getClass());
}
}
Jetzt können Sie innerhalb Ihres Klassencodes einfach verwenden
getLogger().debug("blah blah blah");
Dies ist zwar einfach, hat jedoch einige Nachteile. Zum einen verschmutzt es die Schnittstelle jeder Klasse, die es verwendet, da alle Schnittstellenmethoden öffentlich sind. Vielleicht nicht so schlimm, wenn Sie es nur für Klassen verwenden, die von Spring instanziiert und injiziert werden, insbesondere wenn Sie die Trennung von Schnittstelle und Implementierung befolgen.
Das größere Problem ist, dass bei jedem Aufruf die tatsächliche Logger-Instanz nachgeschlagen werden muss. Welches ist schnell, aber unnötig.
Und Sie benötigen noch eine Importanweisung.
Verschieben Sie den Logger in eine Oberklasse
Ich wiederhole: Ich finde wiederholte Logger-Definitionen nicht ausführlich, aber wenn Sie dies tun, halte ich dies für den besten Ansatz, um sie zu beseitigen.
public abstract class AbstractController {
protected Logger logger = Logger.getLogger(getClass());
}
Jetzt erben Ihre Controller-Klassen von AbstractController
und haben Zugriff auf die logger
Variable. Denken Sie daran, dass Sie die @Controller
Anmerkung in die konkrete Klasse einfügen müssen.
Einige Leute werden dies als eine Perversion der Vererbung empfinden. Ich habe versucht, sie zu beruhigen, indem ich die Klasse benannte AbstractController
und nicht AbstractProjectClass
. Sie können selbst entscheiden, ob es eine Beziehung gibt oder nicht .
Andere Personen lehnen die Verwendung einer Instanzvariablen anstelle einer statischen Variablen ab. Statische IMO- Protokollierer sind anfällig für Fehler beim Kopieren und Einfügen, da Sie explizit auf den Klassennamen verweisen müssen. getClass()
stellt sicher, dass Ihr Logger immer korrekt ist.
getLogger()
den Namen des Loggers angeben, der abgerufen werden soll.