先日書いた「プリミティブ型もCDIでInject」に続いて、今回もCDIの中で知らなかったネタなのですが。
CDIの仕様の中で、@Decoratorを利用してGoFのデザインパターンにあるデコレータパターンを記述する方法があるとのこと。
デコレータパターンについては
辺りがわかりやすいかと。
簡単に書いてみたら、あっさり動きました。
こんなインタフェースを用意して
package jp.co.hoge.decorator;
public interface HogeExecutor {
public void execute();
}
標準出力で「hogehoge」と出すだけの実装クラスを定義します
package jp.co.hoge.decorator;
public class HogehogeExecutor implements HogeExecutor{
@Override
public void execute() {
System.out.println("hogehoge");
}
}
これをデコレーションしてみます。@Decoratorというアノテーションをつけたクラスを用意して、@DelegateをつけたHogeExecutorをInjectして、その周辺をデコるだけ。
package jp.co.hoge.decorator;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;
@Decorator
public class HogehogeDecorator implements HogeExecutor{
@Inject
@Delegate
private HogeExecutor hoge;
@Override
public void execute() {
System.out.println("でこれーしょん");
hoge.execute();
System.out.println("でこでこ");
}
}
このクラスをbeans.xmlに以下のように定義してあげれば
<decorators>
<class>jp.co.hoge.decorator.HogehogeDecorator</class>
</decorators>
とある管理対象Beanとかで
@Inject
private HogehogeExecutor hogehogeExec;
@PostConstruct
public void init(){
hogehogeExec.execute();
}
とかすると標準出力で
でこれーしょん
hogehoge
でこでこ
のように表示されてデコレーションされました。意外と簡単ですね。
クラスの機能拡張=継承、と条件反射的になりがちだけど、こういう道もあるなーと改めて。