「スコープが存在する」と言うことは、「コンポーネントには寿命がある」と言うことだ。たとえばセッションスコープにバインドされたコンポーネントは、セッションの終了とともに不要となる。

つまりコンポーネントにはライフサイクルがあり、コンポーネント内のメソッドでそのライフサイクルに応じて処理を行うことができる。以下がそのライフサイクルだ。

  1. コンポーネントの生成
  2. 依存性の注入
  3. @PostConstructメソッド
  4. @PreDestroyメソッド
  5. @Destroysメソッド

(4以降はコンポーネントの消滅までの流れ)

1のコンポーネント生成は、通常であればWeb Beansコンテナによるコンストラクタ呼び出しによって行われるが、ほかにプロデューサメソッドによるインスタンス生成が行われることもある。これについては後述。

2の依存性注入は、先に説明した「型による依存性解決と注入」によって行われる。

@PostConstructと@PreDestroyはWeb Beansの仕様によるものではなく、「JSR-250:Common Annotations for the Java Platform」で規定された、Javaプラットフォーム共通のアノテーションだ。3と4の間がコンポーネントの生存期間となる。

@Destroysメソッドは、スコープの終了時などに自動的に呼び出される。ステートフル・セッションビーンの場合、@Removeのついたメソッドで代用される (@Removeメソッドが複数ある場合は、@Destroysを同時に指定する必要がある)。

こうしたライフサイクルメソッドをすべて定義するとリスト17のようになる。

リスト17

    @Component @ApplicationScoped
    public class GreetingPrinter {
      private GoodMorning goodMorning;

      public GreetingPrinter() {
        System.out.println("1. コンストラクタ");
      }

      @In
      public void setGoodMorning(GoodMorning goodMorning) {
        this.goodMorning = goodMorning;
        System.out.println("2. 依存性注入");
      }

      @PostConstruct
      public void init() {
        System.out.println("3. @PostContruct");
      }

      @PreDestroy
      public void preDestroy() {
        System.out.println("4. @PreDestroy");
      }

      @Destroys
      public void destroy() {
        System.out.println("5. @Destroys");
      }
    }