7.12. デコレーター

デコレーターは、特定の Java インターフェースからの呼び出しをインターセプトし、そのインターフェースに割り当てられたすべてのセマンティクスを認識します。デコレーターは、何らかの業務をモデル化するのに役に立ちますが、インターセプターの一般性を持ちません。デコレーターは Bean または抽象クラスであり、デコレートするタイプを実装し、@Decorator アノテーションが付けられます。CDI アプリケーションでデコレーターを呼び出すには、beans.xml ファイルで指定する必要があります。

例: beans.xml でのデコレーターの呼び出し

<beans
   xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://xmlns.jcp.org/xml/ns/javaee
      http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd">
   <decorators>
         <class>org.mycompany.myapp.LargeTransactionDecorator</class>
   </decorators>
</beans>

この宣言には 2 つの主な目的があります。

  • システムでデコレーターの順序を指定して、結果が正確になるようにすることができます。
  • デプロイメント時にデコレータークラスを有効または無効にすることができます。

デコレートされたオブジェクトへの参照を取得するために、デコレーターには @Delegate インジェクションポイントが 1 つ必要になります。

例: デコレータークラス

@Decorator
public abstract class LargeTransactionDecorator implements Account {

   @Inject @Delegate @Any Account account;
   @PersistenceContext EntityManager em;

   public void withdraw(BigDecimal amount) {
      ...
   }

   public void deposit(BigDecimal amount);
      ...
   }
}

CDI 1.1 以降、デコレーターは、@Priority アノテーションを使用してアプリケーション全体に対して有効にできます。

@Priority を使用して有効になったデコレーターは、beans.xml ファイルを使用して有効になったデコレーターよりも前に呼び出されます。優先度の値が小さいものが最初に呼び出されます。

注記

デコレーターが @Priority によって有効になり、同時に beans.xml によって呼び出されると、移移植不可能な動作を引き起こします。したがって、複数の CDI 実装全体で整合性のある動作を維持するには、この組み合わせで有効にしないでください。