364

マネージドBeanでは@PostConstruct、通常のJavaオブジェクトコンストラクターの後に呼び出されます。

@PostConstruct通常のコンストラクター自体ではなく、Beanで初期化するために使用するのはなぜですか?

4

4 に答える 4

507
  • コンストラクターが呼び出されたとき、Beanはまだ初期化されていないためです。つまり、依存関係は注入されていません。この@PostConstructメソッドでは、Beanが完全に初期化され、依存関係を使用できます。

  • これは、このメソッドがBeanのライフサイクルで1回だけ呼び出されることを保証するコントラクトだからです。Beanが内部作業でコンテナによって複数回インスタンス化される場合がありますが(可能性は低いですが)、@PostConstruct1回だけ呼び出されることが保証されます。

于 2010-08-04T14:40:04.820 に答える
128

問題は次のとおりです。

コンストラクターでは、依存関係の注入はまだ発生していません*

*明らかにコンストラクタインジェクションを除く


実際の例:

public class Foo {

    @Inject
    Logger LOG;

    @PostConstruct
    public void fooInit(){
        LOG.info("This will be printed; LOG has already been injected");
    }

    public Foo() {
        LOG.info("This will NOT be printed, LOG is still null");
        // NullPointerException will be thrown here
    }
}

重要: Java11では完全に削除され@PostConstructています。@PreDestroy

それらを使い続けるには、 javax.annotation-apiJARを依存関係に追加する必要があります。

Maven

<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

Gradle

// https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api
compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
于 2014-11-27T14:33:21.410 に答える
68

クラスがコンストラクターですべての初期化を実行する場合、@PostConstruct実際には冗長です。

ただし、クラスにsetterメソッドを使用して依存関係が注入されている場合、クラスのコンストラクターはオブジェクトを完全に初期化できず、すべてのsetterメソッドが呼び出された後に初期化を実行する必要がある場合があるため、のユースケースです@PostConstruct

于 2010-08-04T14:46:59.380 に答える
1

また、コンストラクタベースの初期化は、ある種のプロキシまたはリモーティングが含まれる場合は常に意図したとおりに機能しません。

ctは、EJBが逆シリアル化されるたび、およびそのために新しいプロキシが作成されるたびに呼び出されます...

于 2011-10-16T15:34:30.003 に答える