7.12. デコレーター
デコレーターは、特定の Java インターフェイスからの呼び出しをインターセプトし、そのインターフェイスに割り当てられたすべてのセマンティクスを認識します。デコレーターは、何らかの業務をモデル化するのに役に立ちますが、インターセプターの一般性を持ちません。デコレーターは Bean または抽象クラスであり、デコレートするタイプを実装し、@Decorator
アノテーションが付けられます。Contexts and Dependency Injection アプリケーションでデコレーターを呼び出すには、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>
<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); ... } }
@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
によって呼び出されると、移移植不可能な動作を引き起こします。したがって、複数の Contexts and Dependency Injection 実装全体で整合性のある動作を維持するには、この組み合わせで有効にしないでください。