EJB 3.1 と EJB 2.1 の相違点

EJB 2.1 に比べて、EJB 3.1 では Enterprise Java™ Bean アプリケーションの作成プロセスが簡単になりました。

EJB 2.x

J2EE 1.4 アーキテクチャーの複雑度

J2EE 1.4 のアーキテクチャー

ビジネス・レイヤー J2EE 1.4 のアーキテクチャーでは、セッション Bean を使用して、 ビジネス・ロジックのコンポーネントをラップし、 それらのコンポーネントに、トランザクションの分散型リモート、およびセキュリティー・サービスを提供します。 通常は、ファサード・パターンを実装して、クライアントとサービス・プロバイダー間のネットワーク・トラフィックを削減します。 セッション Bean には、ローカル・クライアント (つまり、同じ JVM™ 内にあるクライアント) からも、 リモート・クライアントからもアクセスできます。

メッセージ駆動型 Bean を使用して、外部の JMS プロバイダー (MQSeries® など) を統合し、 非同期メッセージ処理サービスを使用可能にします。

ビジネス・ロジックのレイヤーは、セッション Bean とメッセージ駆動型 Bean の両方で構成されます。 これらがレイヤーと呼ばれているのは、このエンタープライズ・アーキテクチャーの設計で採用されているもう 1 つの基礎的なパラダイムがレイヤー化であるためです。 このレイヤー化により、責任およびスキルの分離、クラスタリング、コンポーネントの再利用などのコア・フィーチャーが使用可能になります。

パーシスタンス・レイヤー もう 1 つの基本的なレイヤーは、パーシスタンス・レイヤーです。 このレイヤーは、アプリケーション・データをリレーショナル・データベース内で永続化することを可能にするサービスとコンポーネントのセットです。 パーシスタンス・レイヤーは以下の方法で実装できます。
EJB 2.x 仕様の問題点

EJB 3.1 のシンプルなモデル

Java EE および EJB 3.1 のアーキテクチャー全体に、 EJB 3.1 モデルの簡素化が反映されています。

EJB 3.1 のアーキテクチャー

EJB 3.1 仕様の基本コンセプトの中心にあるのが、POJO (Plain Old Java Object) プログラミング・モデルです。このモデルでは、 Java 注釈を使用して、 従来はデプロイメント記述子に入っていた情報を取り込みます。 デプロイメント記述子は、一般的にはオプションになりました。 また、デフォルト値の自由な使用は、作成して維持しなければならないサポート・コードの削減にもつながります。 これにより、EJB 3.1 コンポーネントを作成および使用する場合のプログラミング作業が大幅に簡素化されます。 このシンプルなモデルの主なフィーチャーは、以下のとおりです。

表 1. EJB 2.1 と EJB 3.1 との Bean の作成ステップの比較
EJB 2.x でステートレス・セッション Bean を定義するステップ EJB 3.1 でステートレス・セッション Bean を定義するステップ

EJB 2.x 仕様に従ってステートレス・セッション Bean を作成するには、以下のコンポーネントを定義します。

  • EJB コンポーネント・インターフェース: EJB クライアントが Bean の機能へのアクセスを取得する場合に使用します。 ここで、ビジネス・メソッドが定義されます。 コンポーネント・インターフェースは EJB オブジェクトと呼ばれます。 コンポーネント・インターフェースには、以下の 2 つのタイプがあります。
    • リモート・コンポーネント・インターフェース (EJBObject): リモート・クライアントが RMI-IIOP プロトコルを介して EJB にアクセスする場合に使用します。
    • ローカル・コンポーネント・インターフェース (EJBLocalObject): ローカル・クライアント (同じ JVM 内で実行されるクライアント) が EJB にアクセスする場合に使用します。
  • EJB ホーム・インターフェース: EJB クライアントが Bean へのアクセスを取得する場合に使用します。 ここには、作成、検索、または削除の Bean のライフサイクル・メソッドが含まれます。 ホーム・インターフェースは EJB ホームと呼ばれます。 EJBHome オブジェクトは、ホーム・インターフェースを実装するオブジェクトで、EJBObject の場合のように、デプロイ時にコンテナー・ツールから生成されます。ここには、コンテナー固有のコードが含まれます。 起動時に、EJB コンテナーは、デプロイ済みのエンタープライズ Bean の EJBHome オブジェクトのインスタンスを作成し、ネーム・サービスにホームを登録します。 EJB クライアントは、Java Naming and Directory Interface (JNDI) を使用して EJBHome オブジェクトにアクセスします。 ホーム・インターフェースには、以下の 2 つのタイプがあります。
    • リモート・ホーム・インターフェース (EJBHome): リモート・クライアントが RMI-IIOP プロトコルを介して EJB にアクセスする場合に使用します。
    • ローカル・ホーム・インターフェース (EJBLocalHome): ローカル・クライアント (同じ JVM 内で実行されるクライアント) が EJB にアクセスする場合に使用します。
  • EJB Bean クラス: Bean の実際のビジネス・ロジックがすべて含まれます。 ビジネス・ロジックの実装を提供するクラスです。 この Bean クラス内のメソッドは、コンポーネント・インターフェースとホーム・インターフェース内のメソッドに関連します。

EJB 3.1 仕様に従ってステートレス・セッション Bean を宣言するには、単に POJO を定義するだけです。

  • @Stateless
    public class MySessionBean implements MyBusinessInterface {
    // MyBusinessInterface に準拠するビジネス・メソッド
    .....
    }
  • リモート・インターフェースで同じ Bean を公開するには、@Remote 注釈を使用します。
    @Remote(MyRemoteBusinessInterface.class)
    @Stateless
    public class MyBean implements MyRemoteBusinessInterface {
    // EJB メソッド
    .....
    }

EJB 2.1 のクラスおよびデプロイメント記述子ファイルと、同等の EJB 3.1 クラスの比較

テーブル 1 の例は機能的に同等です。

表 2. EJB 2.1 と EJB 3.1 の比較
EJB 2.1 EJB 3.1

Java クラス

public class AccountBean
implements javax.ejb.SessionBean {
 
     SessionContext ctx;
     DataSource accountDB;
 
     public void setSessionContext(SessionContext ctx) {
        this.ctx = ctx;
     }
 
     public void ejbCreate() {
          accountDB = (DataSource)ctx.lookup(
                          "jdbc/accountDB");
 
     }
     public void ejbActivate() { }
     public void ejbPassivate() { }
     public void ejbRemove() { }

     public void setAccountDeposit(int empId,
                                      double deposit) {
       ...
       Connection conn = accountDB.getConnection();
       ...
     }
  ...
}

Java クラス

@Stateless
public class AccountBean implements Account
{
     @Resource private DataSource accountDB;
 
     public void setAccountDeposit(int customerId,
                                      double deposit) {
       ...
       Connection conn = accountDB.getConnection();
       ...
     }
  ...
}

Deployment Descriptor

<session>
  <ejb-name>AccountBean</ejb-name>
  <local-home>AccountHome</local-home>
  <local>Account</local>
  <ejb-class>com.example.AccountBean</ejb-class>
  <session-type>Stateless</session-type>
  <transaction-type>Container</transaction-type>
  <resource-ref>
    <res-ref-name>jdbc/accountDB</res-ref-name>
    <res-ref-type>javax.sql.DataSource</res-ref-type>
    <res-auth>Container</res-auth>
  </resource-ref>
</session>
...
<assembly-descriptor>...</assembly-descriptor>
 

フィードバック