SLF4J ist eine Log -Framework -Abstraktionsschicht, die bestimmte Protokoll -Frameworks wie Log4j, Logback, Java -Protokollierungs -API usw. bindet.
Um SLF4J zu verwenden, müssen Sie eine Abhängigkeit von "org.slf4j: slf4j-api" angeben.
Eine einfache Überprüfung des Fassadenmusters
SLF4J ist eine typische Anwendung des Fassadenmodus. Bevor wir über SLF4J sprechen, lesen wir kurz den Fassadenmodus.
Der Fassadenmodus, dessen Kern darin besteht, dass die Kommunikation mit einem Subsystem über ein einheitliches Aussehensobjekt durchgeführt werden muss, was das Subsystem erleichtert. Die Struktur des Storefront -Musters wird verwendet, um ein Bild darzustellen:
Der Kern des Fassadenmodus ist Fassade, dh das Fassadenobjekt, und der Kern des Fassadeobjekts beträgt mehrere Punkte:
Im Allgemeinen reicht es hier aus, wenn Sie den Store -Modus überprüfen, und Sie werden als nächstes über SLF4J erfahren.
Warum verwenden wir SLF4J?
Warum verwenden wir SLF4J? Zum Beispiel:
Wir verwenden Logback in unserem eigenen System
Unser System verwendet A.Jar und das in A.Jar verwendete Protokollsystem ist log4j
Unser System verwendet B.Jar erneut und das in B.Jar verwendete Protokollsystem ist SLF4J-SOMEPLE
Auf diese Weise muss unser System drei Log-Frameworks unterstützen und verwalten: Logback, Log4j und SLF4J-Simple gleichzeitig, was sehr unpraktisch ist.
Die Art und Weise, dieses Problem zu lösen, besteht darin, eine Anpassungsschicht einzuführen, die bestimmt, welches Protokollsystem verwendet werden soll, und der Anrufer muss nur das Protokoll drucken, ohne sich darum zu kümmern, wie das Protokoll drucken soll. SLF4J oder Commons-Logging ist diese Anpassungsschicht, und SLF4J ist Gegenstand dieser Papierforschung.
Aus der obigen Beschreibung müssen wir eindeutig eine Sache wissen: SLF4J ist nur ein Protokollierungsstandard, keine spezifische Implementierung des Protokollierungssystems. Es ist sehr wichtig, diesen Satz zu verstehen. SLF4J erwähnt nur zwei Dinge:
SLF4J-Simple und Logback sind beide spezifische Implementierungen von SLF4J. LOG4J implementiert SLF4J nicht direkt, aber es gibt eine spezielle SLF4J-Log4j12-Bridge-Brücke, um SLF4J zu implementieren.
Um SLF4J besser zu verstehen, sehen wir uns zuerst die Beispiele an und lesen dann den Quellcode. Ich glaube, die Leser werden ein tieferes Verständnis von SLF4J haben.
SLF4J -Anwendungsbeispiel
Wie oben erwähnt, enthält die direkte/indirekte Implementierung von SLF4J SLF4J-Simple, Logback, SLF4J-Log4J12. Lassen Sie uns zunächst eine pom.xml definieren und das entsprechende JAR -Paket vorstellen:
<!-Originaltext: CANGJIE im Mai http://www.cnblogs.com/xrq730/p/8619156.html-> <projekt xmlns = "http://maven.apache.org/pom/4.0.0" " xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xsi: scheMalocation = "http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven- <modelVersion> 4.0.0 </modelversion> <gruppe> org.xrq.log </GroupId> <ArctifactId> log-Test </artifactid> <version> 1.0.0 </Version> <Packages> jar </packaging> <name> log-test </name> <Url> http://maven.apache.org </url> <url> http://maven.apache.apache <project.build.sourceencoding> utf-8 </project.build.sourceEncoding> </properties> <Deponcies> <abhängigkeit> <GroupID> junit </GroupId> <artifactID> junit </artifactId> <version> 4.11 </Version> <Props> test </scope> </scope> </scope> </scope> </scope> </scope <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <gruppe> org.slf4j </Groupid> <artifactId> SLF4J-log4j12 </artifactId> <version> 1.7.21 </Version> </abhängig> </abhängig> </projekt>
Schreiben Sie einen einfachen Java -Code:
@Testpublic void testslf4j () {logger logger = loggerfactory.getLogger (object.class); logger.Error ("123"); }Als nächstes kommentieren wir zuerst die Zeilen 30 bis 49 von pom.xml oben, dh, wir führen keine SLF4J -Implementierungsklasse ein und führen die Testmethode aus. Werfen wir einen Blick auf die Ausgabe der Konsole als:
Wenn Sie die Ausgabe ohne Protokolle sehen, überprüft dies unsere Ansicht: SLF4J bietet keine spezifische Implementierung von Protokollen, und nur SLF4J können keine Protokolle drucken.
Öffnen Sie dann die Annotation der Logback-Klasse und führen Sie die Testmethode aus. Werfen wir einen Blick auf die Ausgabe der Konsole als:
Ich habe gesehen, dass wir nur eine bestimmte Implementierungsklasse von SLF4J einführen müssen, und wir können das Protokoll -Framework verwenden, um das Protokoll auszugeben.
Schließlich machen wir einen Test. Wir öffnen alle Protokolle, führen Logback-Classic, SLF4J-Simple, Log4j ein, führen Sie die Testmethode aus und die Konsolenausgabe lautet:
Der Unterschied vom oben genannten besteht darin, dass Sie Protokolle ausgeben können, einige Alarmprotokolle werden jedoch ausgegeben, was uns dazu veranlasst, mehrere SLF4J -Implementierungen gleichzeitig einzuführen und dann eines davon als das von uns verwendete Protokollsystem auszuwählen.
Aus dem Beispiel können wir eine wichtige Schlussfolgerung ziehen, dh die Rolle von SLF4J: Solange der gesamte Code das Fassadeobjekt SLF4J verwendet, müssen wir uns nicht um seine spezifische Implementierung kümmern. Am Ende kann an allen Orten eine spezifische Implementierung verwendet werden, und Austausch und Wartung sind sehr bequem.
SLF4J -Implementierungsprinzip
Ich habe mir das obige SLF4J -Beispiel angesehen und werde die Implementierung von SLF4J unten untersuchen. Wir werden uns nur auf den Schlüsselcode konzentrieren.
Die Verwendung von SLF4J ist ein Satz, der das ganze Jahr über unverändert bleibt. Die GetLogger -Methode von LoggerFactory wird implementiert als:
public static logger getLogger (class <?> clazz) {logger logger = getLogger (clazz.getName ()); if (detect_logger_name_mismatch) {class <?> autocomputercallingClass = util.getCallingClass (); if (autocomputedcallingClass! Util.Report ("siehe" + logger_name_mismatch_url + "für eine Erklärung"); }} return logger;}Beginnen Sie mit dem Code aus Zeile 2 und befolgen Sie die Methode Bind () nach loggerFactory:
private endgültige statische void bind () {try {set <URL> staticLoggerbinderPathset = null; // Überspringen Sie unter Android, siehe auch // http://jira.qos.ch/browse/slf4j-328 if (! isandroid ()) {staticLoggerbinderPathset = findpossiblestaticLoggerbinderPathset (); ReportMultipleBindingAmbiguity (staticLoggerbinderPathset); } // In der nächsten Zeile wird die Bindung staticLoggerbinder.getSingleton (); Initialization_state = erfolgreich_initialisierung; ReportActualBinding (staticLoggerbinderPathset); FixSubStituteloggers (); replayevents (); // Alle Ressourcen in subst_factory sub_factory.clear () freigeben; } catch (noclassDeffoundererror ncde) {String msg = ncde.getMessage (); if (messageContainesorgslf4jimplstaticLoggerbinder (msg)) {initialization_state = nop_fallback_initialization; Util.Report ("" Class /"Org.slf4j.impl.staticLoggerbinder/ "nicht geladen wurde."); Util.Report ("Aufwand der No-Openation (NOP) -Logger-Implementierung"); Util.Report ("siehe" + no_staticLoggerbinder_url + "Für weitere Details."); } else {failedBinding (ncde); ncde werfen; }} catch (java.lang.nosuchMethoderror nsme) {String msg = nsme.getMessage (); if (msg! Util.Report ("slf4j-api 1.6.x (oder höher) ist mit dieser Bindung unvereinbar."); Util.Report ("Ihre Bindung ist Version 1.5.5 oder früher."); Util.Report ("Upgrade Ihrer Bindung an Version 1.6.x."); } wirf nsme; } catch (Ausnahme e) {failedBinding (e); Neue IllegalStateException werfen ("unerwarteter Initialisierungsversagen", e); }}Zeile 7 dieses Ortes ist ein Schlüssel. Schauen Sie sich den Code an:
static set <URL> findpossiblestaticLoggerbinderPathSet () {// verwenden Sie anstelle von Liste, um mit dem Fehler #138 // LinkedHashset angemessen zu handeln, da es die Insertionsreihenfolge bei der Iterations -Set <URL> staticLoggerbinderPathset = new linkedHashset <url> () erhalten kann. try {classloader loggerFactoryClassloader = loggerfactory.class.getClassloader (); Aufzählung <url> Pfade; if (loggerFactoryClassloader == null) {paths = classloader.getSystemResources (STATIC_LOGGER_BINDER_PATH); } else {paths = loggerFactoryClassloader.getResources (static_logger_binder_path); } while (paths.hasmoreElements ()) {url path = paths.nextElement (); staticLoggerbinderPathset.add (Pfad); }} catch (ioException ioe) {util.Report ("Fehler beim Erhalten von Ressourcen vom Pfad", ioe); } return staticLoggerbinderPathset;}Der wichtigste Punkt dieses Ortes ist der Code in Zeile 12. Wenn Sie den Eingang von Logger erhalten, finden Sie zum ClassPath, um static_logger_binder_path zu finden. Der Wert static_logger_binder_path lautet "org/SLF4J/Impl/staticLoggerbinder.class", dh alle SLF4J -Implementierungen, unter dem bereitgestellten JAR -Paketpfad muss es "org/SLF4J/Impl/staticLoggerbinder.class" geben. Wir können einen Blick darauf werfen:
Wir können nicht vermeiden, dass mehrere SLF4J -Implementierungen gleichzeitig im System eingeführt werden, daher ist der Empfangsplatz ein Satz. Sie sollten beachten, dass es Warnungen geben wird, wenn der obige Teil Logback, SLF4J-SOMEPLE und LOG4J zur gleichen Zeit wie die Demonstration einführt:
Dies liegt daran, dass es drei "org/SLF4J/Impl/staticLoggerbinder.class" gibt. Zu diesem Zeitpunkt die ReportMultipleBindingAmbiguity -Methode Konsolenausgabe Aussage:
private static void ReportMultipleBindingAmbiguity (set <Url> bindPathSet) {if (isbigousStaticLoggerBinderPathSet (BinderPathset)) {util.Report ("Klassenpfad enthält mehrere SLF4J -Bindungen"); für (url path: bindPathSet) {util.Report ("Found Bindung in [" + path + "]"); } Util.Report ("siehe" + multiple_bindings_url + "für eine Erklärung."); }}Dann können die Internetnutzer fragen, was ich tun soll, wenn es gleichzeitig drei "org/SLF4J/Impl/staticLoggerbinder.class" gibt? Zunächst wird festgestellt, dass dies keinen Fehler beim Start verursacht, und zweitens wählt der Compiler während der Zusammenstellung einen der staticLoggerbinder.class für die Bindung aus.
Schließlich ist staticLoggerbinder relativ einfach. Unterschiedliche staticLoggerbinders haben unterschiedliche Implementierungen von getLoggerFactory. Rufen Sie GetLogger auf und holen Sie sich den spezifischen Logger. Sie können Logger für die Protokollausgabe verwenden.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.