先日書いた「プリミティブ型も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
でこでこ
のように表示されてデコレーションされました。意外と簡単ですね。
クラスの機能拡張=継承、と条件反射的になりがちだけど、こういう道もあるなーと改めて。