デコレータ
今回はデコレータです。
【前提条件】
[環境]
- JDK 1.7.0_07
- Glassfish 3.1.2.2
- PostgreSQL 9.1(JDBC:postgresql-9.1-901.jdbc4.jar)
【サンプルコード】
[インターフェイス]
デコレータのインターフェイスです。
package jp.glory.application; public interface SampleDecoratorApplication { void execute(); }
普通のPOJOです。
[実行クラス]
インターフェイスを実装したクラスです。
package jp.glory.application.impl; import jp.glory.application.SampleDecoratorApplication; public class SampleDecoratorApplicationImpl implements SampleDecoratorApplication { @Override public void execute() { System.out.println("test"); } }
[デコレータ]
機能を追加するクラスです。
package jp.glory.common.decorator; import javax.decorator.Decorator; import javax.decorator.Delegate; import javax.inject.Inject; import jp.glory.application.SampleDecoratorApplication; @Decorator public class SampleDecorator implements SampleDecoratorApplication { @Inject @Delegate private SampleDecoratorApplication applicaiton; @Override public void execute() { System.out.println(applicaiton.getClass().getSimpleName() + "#before"); applicaiton.execute(); System.out.println(applicaiton.getClass().getSimpleName() + "#after"); } }
デコレータのクラスには
javax.decorator.Decoratorアノテーションをつけます。
インターフェイスのimplementsとインジェクションをします。
インジェクションするオブジェクトには
javax.decorator.Delegateアノテーションをつけます。
オーバーライドしたメソッドの中で、
インジェクション↓オブジェクトのメソッドの実行と
前後の処理を追加します。
[beans.xml]
作成したデコレータを有効にするには
beans.xmlに設定を追加します。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://docs.jboss.org/cdi/beans_1_0.xsd"> <decorators> <class>jp.glory.common.decorator.SampleDecorator</class> </decorators> </beans>
decoratorsタグの下に作成したクラスの定義を追加します。
[その他のコード]
[ManagedBean]
package jp.glory.ui.impl; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.inject.Named; import jp.glory.application.SampleDecoratorApplication; @Named(value = "sampleDC") @RequestScoped public class SampleDecoratorPage { @Inject private SampleDecoratorApplication application = null; public void delegate() { application.execute(); } }
他のクラスからインジェクションするときは
デコレータを意識する必要はありません。
[ページ]
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"> <f:view> <h:form id="DecoratorForm"> <h:commandButton action="#{sampleDC.delegate()}" value="テスト" /> </h:form> </f:view> </html>
[実行]
画面からボタンをクリックした時に
出力されたコンソールの結果です。
情報: SampleDecoratorApplicationImpl$Proxy$_$$_WeldSubclass#before 情報: test 情報: SampleDecoratorApplicationImpl$Proxy$_$$_WeldSubclass#after
デコレータとデコレートされたクラスが実行されているのがわかります。