SLF4Jは、Log4J、LogBack、Java Logging APIなどの特定のログフレームワークにバインドするログフレームワーク抽象化レイヤーです。SLF4Jには独自のデフォルトの実装もありますが、主にSLF4Jをログフレームワークの抽象化レイヤーとして使用しています。
SLF4Jを使用するには、「org.slf4j:slf4j-api」への依存性を含める必要があります。
ファサードパターンの簡単なレビュー
SLF4Jはファサードモードの典型的なアプリケーションであるため、SLF4Jについて話す前に、ファサードモードを簡単に確認しましょう。
ファサードモードは、サブシステムとの通信を統一された外観オブジェクトを介して実行し、サブシステムを使いやすくすることです。ストアフロントパターンの構造は、写真を表すために使用されます。
ファサードモードのコアはファサード、つまりファサードオブジェクトであり、ファサードオブジェクトのコアはいくつかのポイントです。
一般的に言えば、ここではストアモードを確認するだけで十分で、次にSLF4Jについて学習し始めます。
なぜSLF4Jを使用するのか
なぜSLF4Jを使用するのですか?例えば:
独自のシステムでログバックを使用します
私たちのシステムはa.jarを使用し、A.jarで使用されるログシステムはlog4jです
私たちのシステムは再びb.jarを使用し、b.jarで使用されるログシステムはslf4j-simpleです
このように、当社のシステムは、ログバック、log4J、およびSlf4j-simpleの3つのログフレームワークを同時にサポートおよび維持する必要があります。これは非常に不便です。
この問題を解決する方法は、使用するログシステムを決定する適応レイヤーを導入することです。発信者は、ログを印刷する方法を気にせずにログを印刷する必要があります。 SLF4Jまたはコモンズログはこの適応層であり、SLF4Jはこのペーパー研究のオブジェクトです。
上記の説明から、1つのことを明確に知る必要があります。SLF4Jは、ロギングシステムの特定の実装ではなく、ロギング標準にすぎません。この文を理解することは非常に重要です。 SLF4Jは、2つのことを行うだけで言及しています。
SLF4J-SimpleとLogBackはどちらもSLF4Jの特定の実装です。 log4jはSLF4Jを直接実装しませんが、SLF4Jを実装するための特別な第一層ブリッジSLF4J-LOG4J12があります。
SLF4Jをよりよく理解するために、まず例を見てからソースコードを読み取ります。読者はSLF4Jをより深く理解すると思います。
SLF4Jアプリケーションの例
上記のように、SLF4Jの直接/間接実装には、SLF4J-SIMPLE、LOGBACK、SLF4J-LOG4J12が含まれます。最初にpom.xmlを定義し、関連するJARパッケージを紹介しましょう。
<! - オリジナルテキスト:5月のCangjie http://www.cnblogs.com/xrq730/p/8619156.html-> <Project 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-4.0.0.0.0.0.0.0.0. <modelversion> 4.0.0 </modelversion> <groupid> org.xrq.log </groupid> <artifactid> log-test </artifactid> <バージョン> 1.0.0 </version> <パッケージ> jar </packaging> <name> log-test </name> <url> http://maven.apache.org. <project.build.sourceencoding> utf-8 </project.build.sourceencoding> </properties> <dependencies> <dependency> <groupid> <groupid> <artifactid> junit </artifactid> <バージョン> 4.11 </バージョン> <scope <groupId> org.slf4j </groupId> <artifactid> slf4j-api </artifactid> <bersion> 1.7.25 </version> </dependency> <dependency> ch.qos.logback </groupid> <artifactid> logback-classic </artifactid> <bertion> 1.2.3 </</< <groupId> org.slf4j </groupid> <artifactid> slf4j-simple </artifactid> <version> 1.7.25 </version> </dependency> <dependency> groupid> log4j </groupId> <artifactid> log4j </artifactid> < <GroupId> org.slf4j </groupId> <artifactid> slf4j-log4j12 </artifactid> <バージョン> 1.7.21 </version> </dependency> </dependencies> </project>
簡単なJavaコードを書く:
@testpublic void testslf4j(){logger logger = loggerfactory.getLogger(object.class); logger.error( "123"); }次に、上記のpom.xmlの30〜49行目を最初にコメントします。つまり、SLF4J実装クラスを導入してテスト方法を実行しません。コンソールの出力を次のように見てみましょう。
ログなしで出力を見ると、これは私たちの見解を確認します:SLF4Jはログの特定の実装を提供せず、SLF4Jのみがログを印刷できません。
次に、Logback-Classic Annotationを開き、テスト方法を実行します。コンソールの出力を次のように見てみましょう。
SLF4Jの特定の実装クラスを導入するだけで、ログフレームワークを使用してログを出力できることがわかりました。
最後に、テストを行います。すべてのログを開き、logback-classic、slf4j-simple、log4jを導入し、テスト方法を実行し、コンソール出力は次のとおりです。
上記との違いは、ログを出力できることですが、一部のアラームログが出力され、複数のSLF4J実装を同時に導入し、そのうちの1つを使用するログシステムとして選択するようになります。
この例から、重要な結論、つまりSLF4Jの役割を引き出すことができます。すべてのコードがファサードオブジェクトSLF4Jを使用する限り、その特定の実装を気にする必要はありません。最終的に、すべての場所で1つの特定の実装を使用でき、交換とメンテナンスは非常に便利です。
SLF4J実装の原則
上記のSLF4Jの例を見て、以下のSLF4Jの実装を研究します。キーコードのみに焦点を当てます。
SLF4Jの使用法は、一年中変化していない文、「Logger logger = loggerFactory.getLogger(object.class);」です。 LoggerFactoryのGetLoggerメソッドは次のように実装されています。
public static logger getLogger(class <?> clazz){logger logger = getLogger(clazz.getName()); if(detect_logger_name_mismatch){class <?> autocomputedCallingclass = util.getCallingClass(); if(autocomputedcallingclass!= null && non matchingclasses(clazz、autocomputedcallingclass)){util.report(string.format( "検出されたロガー名mismatch。 util.report( "see" + logger_name_mismatch_url + "説明のために"); }} return logger;}2行目のコードから始めて、bind()メソッドに従って、loggerFactoryに従います。
private final static void bind(){try {set <url> staticloggerbinderpathset = null; // Androidの下のチェックをスキップします。 ReportMultipleBindingAmbiguity(StaticLoggerBinderPathset); } //次の行は、結合staticloggerbinder.getSingleton()をバインディングします。 initialization_state = sucture_initialization; Reportactualbinding(staticloggerbinderpathset); fixsubstituteloggers(); Replayevents(); //すべてのリソースをsubst_factory sust_factory.clear()でリリースします。 } catch(noclassdeffounderror ncde){string msg = ncde.getmessage(); if(messagecontainsorgslf4jimplstaticloggerbinder(msg)){initialization_state = nop_fallback_initialization; util.report( "class /"org.slf4j.impl.staticloggerbinder/"。 "をロードできなかった。"); util.Report( "デフォルトのNO-OPERATION(NOP)Logger実装"); util.report( "see" + no_staticloggerbinder_url + "詳細については。"); } else {failedbinding(ncde); NCDEを投げる; }} catch(java.lang.nosuchmethoderror nsme){string msg = nsme.getmessage(); if(msg!= null && msg.contains( "org.slf4j.impl.staticloggerbinder.getSingleton()"){initialization_state = failed_initialization; util.report( "slf4j-api 1.6.x(またはそれ以降)は、この結合と互換性がありません。"); util.report( "バインディングはバージョン1.5.5以前です。"); util.report( "バインディングのバージョン1.6.x.にバインディングをアップグレードします"); } nsmeを投げます。 } catch(例外e){failedbinding(e);新しいIllegalStateException(「予期しない初期化障害」、e)を投げます。 }}この場所の7行目は鍵です。コードをご覧ください。
static set <url> findPossiblestaticLoggerbinderPathset(){//リストの代わりにセットを使用して、バグ#138 //挿入順序を適切なバグ#138 // linkedhashsetを処理するために// itecloggerbinderpathset = new linkedhashset = url>(); try {classloader loggerfactoryclassloaser = loggerfactory.class.getClassLoader();列挙<url>パス; 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(path); }} catch(IOException IOE){util.Report( "PATHからリソースの取得エラー"、IOE); } staticloggerbinderpathset;}を返しますこの場所の重要なポイントは、実際には12行目のコードです。GetSloggerの場合、ClassPathにアクセスしてStatic_logger_binder_pathを見つけます。 static_logger_binder_path値は「org/slf4j/empl/staticloggerbinder.class」です。つまり、提供されたJARパッケージパスの下に、すべてのslf4j実装、「org/slf4j/infticloggerbinder.class」が必要です。私たちは見ることができます:
システムに複数のSLF4Jの実装を同時に導入することは避けられないため、受信場所はセットです。上記のパートがログバック、slf4j-simple、およびlog4jをデモンストレーションと同時に導入すると、警告があることに注意する必要があります。
これは、存在する3つの「org/slf4j/impl/staticloggerbinder.class」があるためです。この時点で、ReportMultipleBindingAmbiguityメソッドコンソール出力ステートメント:
private static void reportMultipleBindingAmbiguity(set <url> bindpathset){if(isambiguousstaticloggerbinderpathset(binderpathset)){util.report( "クラスパスに複数のslf4jバインディングが含まれます。"); for(url path:bindpathset){util.report( "[" + path + "]"でバインディングが見つかった。 } util.report( "see" + multiple_bindings_url + "説明について。"); }}その後、ネチズンは、3つの「org/slf4j/empl/staticloggerbinder.class」が同時にある場合はどうすればよいですか?まず第一に、これは起動時にエラーを引き起こさないと判断され、第二に、コンパイル中に、コンパイラはstaticloggerbinder.classの1つをバインディングのために選択します。
最後に、staticloggerbinderは比較的単純です。 StaticLoggerBinderが異なると、GetLoggerFactoryの実装が異なります。 iLoggerFactoryを取得した後、GetLoggerを呼び出して特定のロガーを取得します。 Loggerを使用してログ出力を使用できます。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。