4

私の現在のビルド リーダーは、理論的には素晴らしいアイデアを持っています。つまり、Spring が管理する Bean を取り込んで、それらを使用して標準のログ ファイル以外のさまざまなソースにエラーを記録するカスタム Log4J アペンダーを構築します。ただし、アプリケーション コンテキストを使用して起動時に初期化されるシングルトンを作成する (コードはすぐに説明します) 以外に、Log4J アペンダーで Spring マネージド Bean を取得する他のオプションは考えられないようです。

public class SpringSingleton implements ApplicationContextAware {
    private static ApplicationContext context;
    public SpringSingleton() {
        super();
    }
    public static ApplicationContext getContext() {
        return SpringSingleton.context;
    }
    public void setApplicationContext(ApplicationContext context) {
        if(SpringSingleton.context != null) {
            throw new IllegalStateException("Context is already set!");
        }
        SpringSingleton.context = context;
    }
}

理想的には、これらのプロパティは依存性注入を介して Spring の Bean のように設定できます。初期化されたアペンダーの数に関係なく、Bean 参照は決して変更されません。何か案は?

4

2 に答える 2

7

Spring の前にlog4j を初期化する必要があるため、ブーストラップの問題が発生します。カスタム構成または Log4j の標準イニシャライザを使用しているかどうかにかかわらず、アプリケーション コンテキストが使用される前に起動する必要があります。

ここで、理論的には、カスタムアペンダーを「遅延」して初期化することができます(上記で提案したアプローチを介して、またはアペンダー自体を「セミ」シングルトンにすることにより、たとえば、アペンダークラスにはafterPropertiesSet()メソッドによって入力される静的インスタンスフィールドがあります。そのようにSpring 内でアペンダー自体を Bean として作成できます) が、やや面倒で一貫性がないように見えます。

別のアプローチは、Spring コンテキストが初期化されたら、Log4j を動的に再構成することです。たとえば、をキャッチするリスナーContextStartedEventを作成し、コンテキストからタイプのすべての Bean を取得してAppender、それらを Log4j 構成に追加します。これにより、アペンダーを Bean として作成することもできますが、シングルトンの混乱を多少避けることができます。

于 2009-11-13T18:06:40.357 に答える