JBoss Seamのサンプルアプリを試す。その1
http://docs.jboss.com/seam/reference/en/html/index.htmlを読み始めました。以下は拙い日本語訳です。間違いがあればご指摘下さい。ダウンロードしたSeam一式の中にLGPLとあったので日本語訳していますが、拙いようであればご指摘下さい(Sales宛--しかcontact先はなかった--にE-Mailを送りましたが返事はありません)。
http://docs.jboss.com/seam/reference/en/html/tutorial.html
まずはregistrationサンプルを動かしてみます。
JBoss SeamのサンプルをEclipse上で動かす。にてCVSから持って来たソースをそのまま使います。
- Eclipse上でjboss-seamのbuild.xmlを右クリック Run As-Ant Build
- examples/registrationのbuild.xmlを右クリック Run As-Ant Build
- Debug-JBoss Seam(4.0.3 SP1をdefaultで)にてJBossを起動する。
- http://localhost:8080/seam-registration/register.jsf へアクセス。
で、問題なく動作します。JBoss_Home/server/default/deploy/jboss-seam-registration.earをJBossのDBをPostgreSQL 8.0へ変更する。で作成したJBoss_Home/server/postgres/deploy/へコピーしてJBoss_Home/bin/run.bat -c postgresで再起動しても問題なく動作します。もちろんPostgresのDBにはusersと言うtableが作成されていました。
サンプルアプリケーションregistrationを詳しく見てみます。/examples/registrationの中にあるファイルは以下のものだけです。
プレゼンテーション部分のjspファイルが2つ、SessionBeanのinterfaceとBean、EntityBeanと残りは設定ファイルです。
1. The entity bean: User.java
プロパティに
String username;
String password;
String name;
とこれらのsetter,getterと引数なしのと引数ありのコンストラクタとannotationだけです。
AnnotationとSeam特有部分
-
- @EntityはこのクラスがEJB3.0(The Java Community Process(SM) Program - communityprocess - prのJava Persistence API)で定義されたEntityBeanクラスであるとの宣言です。
- @Name("user")はSeamコンポーネントが必要とするコンポーネント名を定義するものでSeamアプリケーション内で一意でないといけません。JSFがSeamにSeamコンポーネントと同じ名前を使ってコンテキスト変数を解決しようとした場合現在はコンテキスト変数は定義(Null)されていません。Seamはコンポーネントをインスタンス化し新しいインスタンスをコンテキスト変数へバインドします。この場合JSFがuserと名づけた変数を扱う最初にSeamはUserをインスタンス化します。
- @Scope(SESSION)Seamがコンポーネントをインスタンス化したときにはインスタンス化されたコンポーネントはコンポーネントのディフォルトコンテキストにバインドされます。ディフォルトコンテキストは@Scopeで定義されます。UserBeanはセッションスコープのコンポーネントです。
- @TableEJB3.0で定義されたAnnotationでUserクラスはusersテーブルにマップされます。
- クラスのプロパティname,password,usernameはEntityBeanの属性です。全ての永続属性はアクセッサメソッドを定義する必要があります。JSFがレンダーレスポンスやアップデートモデルバリューフェイズでこのコンポーネントを使うときに必要になります。
- 引数なしのコンストラクタはEJB仕様とSeamの両者が必要とします。
- @NotNull,@LengthはHibernateのValidatorフレームワークの一部です。SeamはHibernateのValidatorを進化させデータのValidationに使うことが出来ます(Hibernateを永続化に使ってなくても)
- @IdEJB3.0で定義されたAnnotationでEntityBeanのプライマリーキーを定義します。
このファイルの最も大切なものは@Name,@Scope Annotationです。このAnnotationがこのクラスをSeamのコンポーネントとして成立させます。
以降で述べるようにUserクラスのプロパティはJSFがコンポーネントに直接結合されJSFがアップデートモデルバリューフェイズの間存在させます。JSPページとEntityBeanドメインモデル間でデータをコピーするような退屈なコードを書く必要はありません。
どちらにしてもEntityBeanでトランザクション管理やデータベースへのアクセスを行うべきではない。このコンポーネントはJSFのAction Listerとしては使うことが出来ません。そのためにはSessionBeanが必要です。
2. The stateless session bean class: RegisterAction.java
Seamアプリケーションで最も使うのはSessionBeanをJSFのAction Listerとしてです(代わりにJavaBeanも使えます)。
アプリケーション内でJSFのActionとSessionBeanのメソッドは正確に対応しています。ここではステートレスSessionBeanを使い、UserBeanにより起こされたActionと全ての状態は結び付けられています。
このサンプルアプリケーションでは一番興味あるコードです。
-
- @StatelessはこのクラスがEJB3.0(The Java Community Process(SM) Program - communityprocess - prのEJB 3.0 Simplified API)で定義されたステートレスSessionBeanとしてのクラスのAnnotationです。
- @Scope,@Nameは上記と同じです。
- @Interceptor(SeamInterceptor.class)はSeamコンポーネントとしてのSessionBeanには全てSeamInterceptorをEJB Interceptorとしなければなりません。
- @InはSeamによって注入されたBean属性だと明らかにするものでこの場合user(インスタンス変数名)と名付けられたコンテキスト変数から注入された属性です。
- @ValidはHibernate Validatorから提供されたもので関連するオブジェクトに再帰的にValidationを行います。
- @PersistenceContextはEJB3のEntityManagerを注入するのにつかわれるEJBのAnnotationです。
- SeamはSeamやjBPMコンテキストオブジェクトが注入された、さまざまなJFSが使えます。Seamに注入されたFacesContextインスタンスを得るためにfacesContextインスタンスを@Inと一緒に使っいます。
- @IfInvalidはAction Listenerメソッドが実行される前にHibernate Validatorを使いコンポーネントの状態をValidateするようSeamに伝えます。
- 通常のEJB3の EntityManager APIはAction Listerメソッドを使ってデータベースと協調し、JSFへ出力します。これはSessionBeanですが、registerメソッドが呼ばれてから自動的にトランザクションが開始され完了するとCommitされます。
今回@Scopeが明示的に示されていませんが、その場合はSeamコンポーネントはデフォルトのスコープを持ちます。ステートレスSessionBeanの場合はデフォルトのスコープはステートレスコンテキストです。実際全てのステートレスSessionBeanはステートレスコンテキストに属します。
このアプリケーションではSessionBean Action Listenerはビジネスと永続性のロジックを実行します。もう少し複雑なアプリケーションでは永続性ロジックはデータアクセスコンポーネントに専念するような階層にリファクタリングする必要があるでしょう。実際はそのようにされるでしょう。ただSeamは何層にも及ぶアプリケーションをあなたに課する訳ではないことをお伝えしたいのです。
更に、SessionBeanはWebリクエスト(例えばFacesContextオブジェクト)とトランザクションリソース(EntityManager)を合わせたコンテキストへ同時にアクセス出来ます。これは従来のJ2EEアーキテクチャーを超えるものです。もしあなたが従来のJ2EE層が良いのであればSeamアプリケーションをそのように実装することも出来ます。しかし沢山のアプリケーションは単純に使い物にならないでしょう。
3. The session bean local interface: Register.java
SessionBeanはlocal interfaceを必要とします。
Javaのコードは以上でおしまいです。ここからはDeployment Descriptorsです。