4

ざっと調べてみると、SLF4JとGuice(実際にはどのDIフレームワークでも)は一種の相反する哲学のようです。SLF4Jは、「ねえ、実行時にバインドするクラスがわからないので、それで問題ありません」というアプローチを採用しています。一方、Guiceは、「ねえ、コンパイル時に知る必要があります」と言っているようです。バインドしているクラスを正確に示します。 "。

だから私は尋ねます:Guice / Spring /その他のDIフレームワークを使用してSLF4Jバインディングを構成/注入することは可能ですか?

キッカーは、JavaClassLoaderが、実行時に適切なLogger / LoggerFactory/etcを使用してSLF4Jを実際に「注入」していることです。org.slf4j.impl.Loggerオブジェクトなので、実行時に必要なものを返すようにこれらのClassLoaderを注入する方法がわかりません。

SLF4JとAPIに対するロギングの利点だけでなく、DIの利点も気に入っているので質問します。これを機能させる方法はありますか?前もって感謝します!

4

3 に答える 3

3

それは不可能だと思います(アプリの子クラスローダーを作成するコンテナーなど、非常に面倒なものを作成しない限り...そのようなもの)

置き換え可能な実装を持つSLF4jの基本的な考え方は、バインダーlibが提供することでorg.slf4j.impl.StaticLoggerBinderあり、SLF4JAPIはクラスローダーを介してこのクラスを検索します。したがって、クラスパスに複数のバインダーがある場合、org.slf4j.impl.StaticLoggerBinderそれらが提供しているを区別する方法はありません。DIが発生する前であっても、ロギングフレームワークが初期化されることを考えると、DIフレームワークはこれを支援しません。

SLF4Jが将来その設計を変更しない限り、私たちにできる方法はあまりありません。そして、SLF4Jでもデザインが変わってしまう可能性はないと思います。ロギングの初期化が誰もが依存しているものであることをDIコンテナに伝える方法がないためです。達成するのがほとんど不可能になる理由は他にもあると思います。

しかし、私が疑問に思っているのは、これは本当にDIと関係があるのでしょうか。正直なところ、対応するJARをクラスパスに配置することで、使用するロギングバインディングを制御する問題は見当たりません。プログラムで実行時に制御したい場合は、アプリを起動するための小さなコンテナーを作成するのが良い方法だと思います。ただし、それでもDIとは関係ありません。

于 2012-10-26T03:47:48.993 に答える
1

この問題に対するかなり単純なアプローチの1つは、メソッドを介してILoggerFactoryインスタンスをに注入することです。(2012年10月現在、この方法は存在しません。) LoggerFactorysetILoggerFactory()setILoggerFactory()

SLF4Jによって現在実装されている静的バインディングメカニズムは、の設定以外にはほとんど何もしませんILoggerFactory。そのようなアプローチはあなたのために働きますか?

于 2012-10-26T11:28:18.687 に答える
1

これを今見つけている人のために:Sangriaは、これに非常にうまく機能する「コンテキスト依存バインダー」を実装しています。具体的に参照sangria-slf4jしてください。sangria-contextual

著者のブログ投稿から、次のように簡単にロガーファクトリという名前のSLF4Jを設定できます。

public class YourModule extends AbstractModule {
    @Override
    protected void configure() {
        install(new SangriaSlf4jModule());
    }
}

...そして、あなた自身のタイプのために新しいプロバイダーを使用する方法の例もあります。

于 2016-12-21T16:04:24.407 に答える