
第4回 疑似EJB 3.0環境をSpringとXDocletで作る
西ヶ谷岳(サン・マイクロシステムズ)
2005/10/20
Page.1 | Page.2 |
第1回の「JSF・Spring・Hibernateで次世代Javaに備える」で述べたように、EJB 3.0ではビジネス層のサービス・オブジェクトはPOJOとして実現できます。また、AOPの機能が利用可能となり、ビジネスロジックに手を加えることなく、特定の前処理や後処理をビジネスロジックに織り込むことができるインターセプターを利用することができるようになります。
今回は、上記のようなEJB 3.0と同等の環境を構築します。そんなことが簡単にできるだろうか、と疑問に思われる方もいるかもしれません。しかし、SpringフレームワークやXDocletを応用することで、それほど工数を掛けずにEJB
3.0にかなり近い開発環境を用意することができるのです。
![]() |
|
サービス・オブジェクトをPOJOでデザインする |
ここでの目標は、サービス・オブジェクトをPOJOとして実装できるようにすることです。すなわち、以下の例のように、特定の環境やライブラリに依存せず、階層化アーキテクチャに基づいて分離したほかのレイヤのコンポーネントとの依存関係は、それらのインターフェイス定義のみによって依存するようにサービス・オブジェクトを定義します。
public interface CustomerService { |
リスト2 CustomerServiceの実装クラス
public class CustomerServiceImpl implements CustomerService { |
顧客情報の検索や削除の実際の処理は、インテグレーション層のデータ・アクセス・オブジェクトCustomerDAOに委譲するため、CustomerDAOをCustomerServiceにインジェクションするためのsetterメソッドも用意しています。Java EE 5環境が利用可能になれば、CustomerDAOのインジェクションには以下のような@Resourceアノテーションによってワイヤリングできるでしょう。
@Resource(name="CustomerDAO") |
J2EE 1.4ベースの現状では、アノテーションの代わりに、SpringフレームワークのXMLメタデータを利用したワイヤリングで代用します。
<bean name="CustomerService" |
![]() |
|
POJOのサービスオブジェクトをEJBでラップする |
ビジネス・オブジェクトにEJBを利用するメリットは、第2回「鍵はPOJOベースのアプリケーション・デザイン」にも述べたとおりJ2EE 1.4標準技術で、トランザクション管理やロールベースのアクセス制御が実現できるからです。そして、EJBを利用したビジネスロジックには、トランザクションやアクセス制御のコードは一切記述する必要がない環境がすでにあるわけです。
しかし、EJBは特定のインターフェイス(すなわち、SessionBeanインターフェイス)を実装し、決められたルールに従ってメソッドを実装しなければいけません。制約の少ないPOJOベースデザインとEJBの優れた機能の両方のメリットを得るためには、サービス・オブジェクトのビジネス・メソッドをデレゲート呼び出しするセッション・ビーンを用意すればよいことになります。
リスト3 CustomerServiceSessionBean.javaimport org.springframework.ejb.support.AbstractStatelessSessionBean; |
すなわち、POJOのビジネスメソッドと全く同じシグネチャのメソッドを用意し、セッション・ビーンのビジネスメソッドが呼び出されたら、POJOのビジネスメソッドを単に呼び直せばよいのです。後は、セッション・ビーンにどのようにして、POJOのサービス・オブジェクトの参照を与えてあげるかを考えればよいことになります。
Springフレームワークにはjavax.ejb.SessionBeanインターフェイスを実装したアダプタークラスAbstractStatelessSessionBeanが用意されています。上記のように、getBeanFactory()メソッドを経由して、Spring管理化のビーンを取得することができますので、ここではこれを利用することにしましょう。
セッションビーンの実装にSpringフレームワークのクラスへの依存間関係が生じますが、Java EE 5になったら、POJOのサービス・オブジェクトの実装だけが必要になり、このEJBの実装は捨ててしまえばいいわけですから、ここではSpringのAbstractStatelessSessionBeanへの依存性に神経質になる必要はないでしょう。
ここまでで来てしまえば、EJB実装に必要なリモート/ローカルインターフェイスやホームインターフェイス、デプロイメント記述子(ejb-jar.xml)は、XDocletによって自動生成させてあげることができます。以下は、antコマンドからXDocletを呼び出す実行例です。
$ ant ejb.xdoclet
$ find build/ -type f |
実際には、上記の各種ファイルを自動生成するためには、リスト3のCustomerServiceSessionBeanに対してXDocletが認識できるメタデータ(@で始まるjavadoc形式のタグ)をいくつか記述する必要があります。
XDocletに必要なantビルドファイルの記述方法については、サンプルコードのアーカイブファイルに含まれるbuild.xmlファイルを参照してください。
![]() |
|
カスタムDocletでEJBを自動生成する |
現在のところXDocletはまだJDK 1.5のアノテーションには対応していません。そのため、リスト3のEJB本体のCustomerServiceSessionBeanだけは手作業で作成する必要があります。このクラスは比較的簡単に実装できますが、アプリケーションの規模が大きくなってくるとそれなりの工数が発生します。また、サービス・オブジェクトのインターフェイスが変更になれば、それに同期してEJBのインターフェイスも修正しなければなりません。
そこで、上記のEJB自動生成の仕組みを一歩進めて、リスト3のEJB本体も自動生成することを考えます。そうすればJava EE 5と同様、EJBを全く意識せずに、サービス・オブジェクトをEJBコンテナで動作させることができるのです。
セッション・ビーンの自動生成の入力データとしては、リスト1のサービス・インターフェイスにXDocletのトランザクション属性やアクセス制御属性を含んだものを利用します。
リスト4 CustomerServiceインターフェイスpublic interface CustomerService { |
Javaのソースコードを読み込んで別のソースファイルを生成するためには、javadocコマンドを用いた、カスタムDocletを作成するのが最も簡単です。javadocコマンドはantコマンドからも実行できますので、以下のような使い方を想定するものとします。
リスト5 EJB本体を生成するantターゲットの定義 <target name="ejb.create" depends="compile" |
カスタムDoclet CreateSessionBeanDocletの-dirオプションには生成したセッション・ビーンのソースを保存するディレクトリを指定し、-contextオプションにはEJBコンテナで使用するSpringの設定ファイル名を指定するものとします。
カスタムDocletの作成はそれほど難しいものではありません。Docletにstart(RootDoc)メソッドを定義すると、Docletに読み込まれたソースコードをJavaからナビゲートしやすい形式にしたメタオブジェクトとしてアクセスできるようになります。メタオブジェクトは、RootDocを頂点として、ClassDoc(クラスのメタオブジェクト)の配列が取得でき、ClassDocからMethodDoc(メソッドのメタオブジェクト)の配列が取得できます。従って、ClassDoc、MethodDocのメタ情報を基にセッション・ビーンのソースの断片を生成するソースジェネレータクラスとして、それぞれClassGeneratorクラス、MethodGeneratorクラスを用意すればよいことになります。
![]() |
図1 EJB自動生成のためのカスタムDocletの構成 |
ソースコードの自動生成といっても、実際にはあらかじめ用意しておいたテンプレートファイルの変数に対して、得られたメタオブジェクトの情報を埋め込んでいくだけです。例えば、セッション・ビーンのメソッド部分については、以下のようなテンプレートを用意します。
リスト6 MethodGeneratorクラス用テンプレート/** |
MethodGeneratorクラスのgenerate()メソッド内では、リスト6のテンプレートの%変数名%の部分をメタオブジェクトの情報で置き換えていきます。
リスト7 MethodGeneratorのgenerate()メソッドclass MethodGenerator { |
ここのサンプルコードのアーカイブファイルにはCreateSessionBeanDocletの完全な実装が含まれています。同梱されているREADME.txtファイルの内容に従って、必要なライブラリを配備した後、ターゲットejb.createを指定してantコマンドを実行してみて下さい。リスト3のEJB本体のソースが生成されることを確認できると思います。
$ ant ejb.create |
1/2 | ![]() |
INDEX |
||
第4回 疑似EJB 3.0環境をSpringとXDocletで準備する | ||
![]() |
Page1 サービス・オブジェクトをPOJOでデザインする POJOのサービスオブジェクトをEJBでラップする カスタムDocletでEJBを自動生成する |
|
Page2 Springプロキシー機能を利用してEJBサービスオブジェクトを取得する EJB 3.0に移行可能なインターセプターを実装する Tomcatでもトランザクションやアクセス制御の動作確認をするためには |
![]() |
Java Solution全記事一覧 |
- 実運用の障害対応時間比較に見る、ログ管理基盤の効果 (2017/5/9)
ログ基盤の構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。今回は、実案件を事例とし、ログ管理基盤の有用性を、障害対応時間比較も交えて紹介 - Chatwork、LINE、Netflixが進めるリアクティブシステムとは何か (2017/4/27)
「リアクティブ」に関連する幾つかの用語について解説し、リアクティブシステムを実現するためのライブラリを紹介します - Fluentd+Elasticsearch+Kibanaで作るログ基盤の概要と構築方法 (2017/4/6)
ログ基盤を実現するFluentd+Elasticsearch+Kibanaについて、構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。初回は、ログ基盤の構築、利用方法について - プログラミングとビルド、Androidアプリ開発、Javaの基礎知識 (2017/4/3)
初心者が、Java言語を使ったAndroidのスマホアプリ開発を通じてプログラミングとは何かを学ぶ連載。初回は、プログラミングとビルド、Androidアプリ開発、Javaに関する基礎知識を解説する。
![]() |
|
|
|
![]() |