14

シングルトンアプローチに従って実装されたクラスにロガーオブジェクトを注入しようとしています。

コードはほぼ次のようになります。

Loggerクラス:

public class LoggerFactory {
    @Produces 
    public Logger getLogger(InjectionPoint caller){
        return Logger.getLogger(caller.getMember().getDeclaringClass().getName());
    }
}

次に、ロガーを必要とし、シングルトンパターンを実装するクラスを作成します。

public class MySingleton{
    @Inject
    private Logger logger;

    private MySingleton instance;

    /*
     * Private constructor for singleton implementation
     */
    private MySingleton(){
        logger.info("Creating one and only one instance here!");
    }

    public MySingleton getInstance(){

        if(instance == null) {
            instance = new MySingleton();
        }

        return instance;
    }

}

(Glassfish 3.1.2.2で)コードを実行すると、ロガーを使用しようとするとすぐにNPEが取得されます。私が間違っていること(beans.xmlファイルが配置されている)?また、オブジェクト@Injectのセッターメソッドを使用してみましたが、うまくいきませんでした。Logger

4

2 に答える 2

24

注入は構築後に行われます。したがって、コンストラクターで使用することはできません。

1つの方法は、注入後に呼び出すことができる@PostConstructという注釈の付いたメソッドを追加することです。

@PostConstruct
public void init() {
    logger.info("Creating one and only one instance here!");
}

ちなみに、私はあなたが間違った方法で問題を引き起こしていると思います。CDIは素晴らしいシングルトンサポートを持っています

@Singletonという注釈の付いたクラスを作成します

@Singleton
public class MySingleton {

    @Inject
    Logger logger;

    @PostConstruct
    public void init() {
        logger.info("Creating one and only one instance here!");
    }

}

上記は、Java ee(JSR-299)にCDIを使用していることを前提としています。

JSR 330依存性注入(guiceなど)リンクを使用している場合

コンストラクタインジェクションを使用できます。

@Singleton
public class MySingleton {


    private final Logger logger;

    @Inject
    public MySingleton (Logger logger) {
        this.logger = logger;
        logger.info("Creating one and only one instance here!");
    }
}
于 2013-02-28T14:55:31.137 に答える
4

すでに述べたように、コンストラクターが呼び出された後にインジェクションが実行されるため、これは機能しません。

で注釈@PostConstructが付けられたメソッドは、インジェクションが終了した後、オブジェクト自体が別の場所に提供される前に呼び出されます。

ただし、インジェクションは、クラスのインスタンスがインジェクション自体によって提供される場合にのみ機能します。これは、プロキシに依存するインジェクションによるものです。

したがって、必要な場所にMySingletonを注入する必要があります。シングルトンであることを確認するために、注釈を付ける@Singletonと、コンテナがそれを処理します。

さらに、CDI仕様に関するシングルトンは、1つのインスタンス化だけを意味するのではなく、の1つの初期化のみを意味することに注意してください@PostConstruct

于 2013-02-28T14:56:20.887 に答える