EJBなどについて、今日調べたこと

アプリケーションのパフォーマンスを計測のコードを内包させるのではなく、コンテナのCall StatisticsやHibernateの統計、データベースが提供する統計値を駆使する。

コネクションプールでの最小接続数、最大接続数はチューニングすべき。またプリペアード・ステートメント・キャッシングも設定すべき。利用していないコネクタのスレッドプールは削除すべき。

本番環境では、コンソールロギングをOFFにする。

アプリケーションサーバで、必要とされるサービスだけを動かす。ホットデプロイも使わないなら無効にする。

EJB3.1仕様(http://www.jcp.org/en/jsr/detail?id=318)では、EJBコンポーネントを直接WARの中に入れてデプロイできる。EJBタイマーが自動的に生成される(ステートレスとシングルトンのセッションオブジェクトの場合にだけタイマーをセットできる)。stateful、stateless、singletonの3種類のsession bean(クライアントの要求に応えるセッションオブジェクト)が存在する。クライアントからのメッセージ受信時に実行されるメッセージ駆動オブジェクト。データベース内のデータをオブジェクトとして表現するエンティティオブジェクト。

Managed Beans 1.0 Specificationは、コンテナ管理オブジェクトの最低限の要件を規定する。セッションBeanコンポーネントは、Managed Beanである。

クライアントは、セッションBeanを同期、または非同期で呼び出すことができ、非同期の場合は、Futureオブジェクトを用いて、結果の取得や、処理のキャンセル等を行うことができる。詳細はjava.util.concurrent.FutureのJavadocを参照。@Asynchronousの付いたビジネスメソッド、または@Asynchronousの付いたクラスのビジネスメソッドが非同期のメソッドである。Bean側は、SessionContext.wasCancelCalled()を呼ぶことで、クライアントからのキャンセルを知ることができる。戻り値がvoidの非同期メソッドの場合、メソッド内で例外が起きても、クライアントに知らせる術はない。

クライアントは、セッションBeanのビジネスインタフェースをdependency injection、またはJNDIネームスペースのルックアップによって取得することができる。セッションBeanがリモートにあるときも、ローカルにあるときも、同じように記述する。

dependency injectionの例
@EJB Cart cart;

JNDIネームスペースルックアップの例
@Resource SessionContext ctx;
...
Cart cart = (Cart)ctx.lookup(“cart”);


セッションBeanがステートフルな場合、cart1 != cart2 だが、ステートレスの場合は、cart1 == cart2である。

@EJB Cart cart1;
@EJB Cart cart2;


ステートフルセッションBeanのconversational stateは、ステートフルセッションBeanインスタンスのフィールド値として定義される。ステートフルセッションのフィールド値は、passivateによって、二次ストレージにシリアライズされることがある。passivate時にステートフルセッションBeanが呼び出されると、activateによって元に戻されて実行が継続する。@StatefulTimeoutで、ステートフルセッションBeanがアイドル状態であり続けることのできる時間を指定する。

コンテナは、ステートレスBeanとステートフルBeanのメソッドをシリアライズして(1度に1つずつ)呼び出すので、それぞれのメソッドを、リエントラント(再入可能)にする必要はない。また、メソッドの中で自分を再帰的に呼び出すこと(ループバックコール)はできない。コンテナは複数のクライアントからのステートレスBeanへのリクエストをステートレスBeanのそれぞれ別のインスタンスに割り振る。

シングルトンBeanのインスタンスはアプリケーション内に一つだけ存在し、すべてのクライアントに共有されるので、同時にアクセスできる仕組みが必要である。Container Managed Concurrencyを利用した場合、メソッド呼び出しにReadまたはWriteのロックを指定することができる。

クライアントにおいて、メッセージの宛先は、以下のようにインジェクションされるか、JNDIの名前空間でルックアップされる。

@Resource Queue stockInfoQueue;

Context initialContext = new InitialContext();
Queue stockInfoQueue = (javax.jms.Queue)initialContext.lookup
(“java:comp/env/jms/stockInfoQueue”);

メッセージ駆動Beanはコンテナの中で管理され、実行される。複数のインスタンスが同時に実行可能だが、ひとつのインスタンス内のメソッドが同時に実行されることはない。