Webアプリケーションにおける
サーバ・サイドJavaの効果的な利用
(後編)

EJBアーキテクチャの基礎

伊藤敬
日本BEAシステムズ

2000/11/8

今回のおもな内容
EJBの基本的なアーキテクチャ
EJBコンテナはシステムの中核
EJBコンテナが提供する機能
セッションBeanとエンティティBeanの役割

前回の記事ではEJB(Enterprise JavaBeans)の概要とメリットを典型的なシステム構築事例と合わせて紹介した。今回は、EJBの基本的なアーキテクチャを解説する。特に、アプリケーションサーバのEJBコンポーネント・テクノロジの中核である「EJBコンテナ」の機能と、セッションBean、エンティティBeanの役割と機能を中心に紹介しよう。


   EJBの基本的なアーキテクチャ

 まずはEJBを取り巻く環境から見ていきましょう。EJBベースのシステムを外から見てみます。システムの基本的なアーキテクチャは3層構造であり、

  • クライアント
  • EJBサーバ
  • データベース(その他の保管可能なストレージ)

    から構成されていることがわかります。ただし、これらは物理的に分割されている必要はありません(図1)
  • 図1 EJBベースのシステムの基本的なアーキテクチャ

     クライアントはリモート環境に存在するEJBサーバ内のEJBを呼び出します。この時、クライアントはEJBクライアントと呼ぶことができます。EJBサーバはEJBコンテナを包含しています。EJBコンテナはEJBコンポーネントの動作環境です。EJBはデータベースにアクセスできます。あるいは、EJBコンテナにEJBが持つデータの管理を任せることもできます。EJBクライアントはEJBへダイレクトにアクセスすることはありません。EJBクライアントはEJBコンテナが提供するEJBのHomeインターフェイスとRemoteインターフェイスを介してEJBとの通信を行います(図2)。HomeインターフェイスはEJBに必ず必要なインターフェイスクラスです。このインターフェイスはRMI(Remote Method Invocation)クラスからの拡張であり、EJBはローカルとリモート間の通信手段としてRMIを用いています。

    図2 EJBクライアント、EJBサーバ、EJBコンテナの関係

     EJBの仕様では、EJBサーバはクライアントとEJBの通信に関して役割を持っていません。また、EJBサーバとEJBコンテナの間での明確な役割分担も定義されていません。概念的には、EJBサーバは「EJBコンテナのコンテナ」であるといえます。EJBサーバはEJBコンテナに対し、低レベルのサービス(例えばネットワークへの接続など)を提供します。また、クライアントはEJBを呼び出す際、JNDI(Java Naming and Directory Interface)を利用します。

       EJBコンテナはシステムの中核

     アプリケーションサーバを使ってEJBベースのシステムを構築する場合、EJBコンテナがシステムの中核になります。EJBコンテナの役割の中でも重要なのは、EJBによる機能提供を効率的に行うためにEJBとEJBサーバの間にバッファを用意し、運用すること、そしてEJBの生産性と再利用性が高まるよう、各種の必要不可欠なサービスをバックグラウンドで提供することです。バッファはEJBと関連するリソースのプールとして、複数のインスタンスを保持します。また、EJBコンテナは主に以下のようなサービスを提供します。

    • トランザクション管理
    • リソース管理
    • EJBライフサイクル管理
    • インスタンス・ステート管理
    • パーシスタンス
    • セキュリティ

     J2EEのサービス群はEJBコンテナ、EJB、EJBクライアントが利用します。J2EEはEJBとEJBクライアントの中で開発者がプログラミングによって利用する場合と、EJBコンテナがバックグラウンドで利用する場合があります。詳細についてはアプリケーションサーバ製品のマニュアルなどを参照していただければ、お分かりいただけると思います(ご参考に弊社のアプリケーションサーバ製品、BEA WebLogic Serverのマニュアルをご覧ください)。ここではEJBコンテナの特長でもある上記の機能を紹介します。

       EJBコンテナが提供する機能

     EJBコンテナが提供する機能は、EJBを開発する際に要するプログラミング量を削減するとともに、EJBアーキテクチャを簡素化し、効率的で信頼性の高いシステムを提供するという重要な意味を持っています。各ベンダが提供しているアプリケーションサーバ製品は以下に示す機能をベースに、さらにベンダ独自の機能を提供している場合があります。

    ■トランザクション管理
     宣言型トランザクション管理を利用してEJBをトランザクション処理に組み込むことができます。宣言型トランザクション管理とは、EJBクライアント、EJBコンテナ、EJBの間でどのようなトランザクションを行うかをあらかじめ属性値によって宣言しておくことでEJBコンテナがトランザクションを自動的に制御します。これによってEJB内部で余計なプログラミングが発生しません。EJBコンテナは、EJBクライアントがEJBを呼び出すタイミングで指定された属性に従ってトランザクションを開始したり、クライアントが開始したトランザクションを保留したりといった制御を行います。宣言型トランザクションにはいくつかの属性があり、用途に応じて使い分けます。どの属性を利用するかはEJBの属性ファイルである「デプロイメント・ディスクリプタ」に開発者が記述します。

     トランザクション属性には以下のような種類があります。

    属性
    内容
    Required クライアントがトランザクションを開始していればその中でEJBのメソッドが実行される。トランザクションを開始していなければEJBコンテナが開始する
    RequiresNew EJBメソッドへの呼び出しごとに新しいトランザクションを開始・終了する
    Mandatory クライアントが必ずトランザクションを開始している必要がある
    NotSupported クライアントが必ずトランザクションを開始しているかどうかに関わらず、EJBのメソッド実行はその中に含まれません
    Supports クライアントがトランザクションを開始していればその中でEJBのメソッドが実行される。トランザクションを開始していなければEJBコンテナは何もしない
    Never EJBメソッドは、トランザクションに参加しない

     この機能とは別に、プログラミングによってEJB内部で通常のトランザクション処理を記述することもできます。その場合、JTA/JTS(Java Transaction API / Java Transaction Service)を用いたプログラミングを行うことになります。

    ■各リソース管理
     EJBコンテナはEJB自身、および関連するリソースの管理を行います。リソースの種類としては、スレッド、ソケット・コネクション、データベース・コネクションなどです。これらのリソースをどのくらい確保し、運用するかは多くのアプリケーションサーバの場合、搭載された管理ツールから操作できるようになっています。

    ■Beanライフサイクル管理
     EJBコンテナはデプロイされたEJBのライフサイクルを管理します。EJBコンテナはクライアントからのリクエストの処理をリソース配分などを考慮しながらEJBに渡します。EJBはリソースプールから呼び出されるか直接インスタンス化されるかしますが、同時に処理終了後どう処分されるかもEJBコンテナが管理します。

    ■インスタンス・ステート管理
     EJBはJavaのクラスとして、シンプルな単一スレッド上で動作し、ただ1つのクライアントからアクセスされるものとして記述されます。このことはステートレス セッションBeanなどにはそのとおりですが、他のBeanは複数のクライアントからのアクセスを許します。従ってEJBコンテナは各EJBクライアントからのリクエストが規則に準じたものとなるようにEJBに対して保証します。このため、EJBコンテナは以下のようなしくみを持っています。

    属性
    内容
    インスタンス・
    パッシベーション
    EJBを一時的にストレージ領域に待避させる機能。セッション Beanに対してはEJBコンテナのフリー領域を増やす働きを持ち、エンティティ Beanに対しては、データストアとの状態のシンクロに利用される

    インスタンス・
    プーリング
    ステートレス セッション Beanなどの場合、少数のインスタンスを効率的に利用する手段として、一度生成したインスタンスをプールしておき、他のクライアントからコールされた場合に再度活用する機能
    DBコネクション・
    プーリング
    EJBコンテナがEJBサーバの起動時などにデータベースのコネクションを任意の数生成し、プールしておく。これによってコネクションを生成する時間的なロスを防ぎ、リソースの利用も効率化する
    プリキャッシュド・インスタンス EJBのインスタンスが生成される際、データベースから状態データを取り込む場合がある。そのような場合のインスタンス生成時間を短縮するため、メモリやデータベースのテーブルなどのアクセスしやすい場所にEJBの状態情報をあらかじめ置いておくことができる。これによってEJBの初期生成にかかる時間を短縮できる

    ■パーシスタンス
     パーシスタンスはデータベースやファイルなどのストレージに対してオブジェクトの保存を提供する機能です。そのオブジェクトは新たに生成されるのではなく、読み出されます。どのようなタイミングでパーシスタンスを使用するかはあらかじめセットしておくことができ、EJBコンテナがその管理を行います。また、パーシスタンスの方法については開発者が実装する方法とEJBコンテナに任せる方法があり、それぞれをBM(ビーンマネージド パーシスタンス)、CMP(コンテナマネージド パーシスタンス)と呼びます。

    ■セキュリティ
     EJBのセキュリティとしてアクセス・コントロール・リスト(ACL)が定義されています。ACLはBean、あるいはそこに定義されたメソッドに対してどのユーザ、グループがアクセスできるかを定義したリストです。

       セッションBeanとエンティティBeanの役割

     前回はセッションBeanとエンティティBeanについて、ほんのさわりの部分をご紹介しました。セッションBeanにはステートフルセッションBeanとステートレスセッションBean、エンティティBeanには永続化の手段が異なるBMP(ビーンマネージドパーシスタンス)、CMP(コンテナマネージドパーシスタンス)エンティティBeanがあります。

     まずは簡単なモデルを使って、セッションBeanとエンティティBeanの役割の違いをご説明しましょう。セッション Beanはビジネスプロセスを表すものであり、通常ビジネスロジックを包含しています。これに対してエンティティ Beanは永続的なビジネスエンティティを具現化しています。エンティティBeanは通常リレーショナル・データベースにマッピングされており、1つのBeanが1レコードとして管理されます。

     前回用いたオンライントレーディング会社の個人向け証券取引システムを例にセッションBeanとエンティティBeanの役割を説明してみましょう。このシステムは顧客の証券売買オーダを計算し、注文情報を購入処理に渡すという機能を持っています(図3)

    図3 あるオンライントレード証券取引システムのシステム図

     たとえば顧客がある株式を購入する場合、その株式を何株購入するか、注文情報としてクライアントに入力します。システムは証券別の購入額と合計購入額を計算します。この時の計算ロジックをEJBコンポーネント化したものがセッションBeanです。この計算コンポーネントはクライアントから情報をもらい、計算を実行し結果を返すだけです。同時に計算結果は注文情報として購入処理に利用されることになります。計算コンポーネントは処理が終わるとクライアントから切り離され、別のクライアントからの計算要求を受け付けます。その後顧客が、約定(市場における株売買の決定)前に購入する株式の株数を変更したいと要求したとします。この時、注文情報自身はまだ処理されておらず、そのままの状態で保持されています。これをコンポーネント化したものがエンティティBeanです。顧客からの購入オーダは一度システム上に注文として発生すると一般的には何らかの変更指示が出されるまで変更することはありません。

     つまり、この時購入オーダは永続的な状態であると言えます。この永続的な状態はオーダが消滅するまで(一般にはシステムに約定通知が届くまで)続きます。これまでのRDBMSと連携するクライアント・サーバ型システムであれば、中間データベースを配置して、顧客のオーダ情報を持たせることになる部分です。この場合、中間データベースへの保存や更新についての処理はすべてリレーショナルデータベースのテーブルとカラムへの入出力をベースにプログラミングする必要がありました。エンティティBeanを用いれば、オブジェクトをプログラミングのベースとすることができると同時にビジネスエンティティのしくみをアプリケーションサーバ(EJBコンテナ)が提供してくれることになります。これがEJBの再利用性と生産性、信頼性の重要なポイントです。

     また、注文情報は購入処理を行う他のアプリケーションによって処理されます。このアプリケーションは別のセッションBeanを含み、ビジネスロジックを独自に持ちます。この実行によって注文が処理され、エンティティBeanとして存在した注文が処理されます。

      このように、一連の処理を眺めてみるとセッションBeanとエンティティBeanが明確な階層を持っていることがわかります。セッションBeanはビジネスロジックを持ち、エンティティBeanにアクセスします。エンティティBeanはその背後でデータベース管理を行っています。つまり、アプリケーションの処理を階層化し、ワークフロー部分(ビジネスロジック)とエンティティ部分、そしてデータベース処理の隔離がうまく切り分けられ、独立した構造となっているわけです。EJBをベースとするシステム開発とは、オブジェクト指向設計・開発が非常にスムーズに行かされる環境であるといえるわけです。もちろん、セッションBeanもデータベースにアクセスでき、テーブルを更新することができます。しかし、永続的にデータを保持することはできません。役割は明確に分けられているのです。

     ここまでで、セッションeanとエンティティeanの性質の違いをご理解いただけたと思います。では次に、それぞれが持つ2つのBean、ステートレスセッションBeanとステートフルセッションBean、ビーンマネージド・パーシスタンスとコンテナマネージド・パーシスタンスについて説明します。

    ■セッションBean
    セッションBeanはビジネスロジックを持ちます。その名のとおり、クライアントとのセッションの間が基本的なlifetimeです。クライアントからの呼び出しによってEJBコンテナがインスタンスを生成します。クライアントとBeanのインスタンスとは1対1であり、複数のクライアントからのアクセスはできません。クライアントは直接Beanのインスタンスを生成・管理・消滅させることはできません。これらの処理はすべてEJBコンテナが行います。

    ■ステートレスセッションBean
    ステートレスセッションBeanは匿名のメソッド・プロバイダにたとえられます。匿名であること、つまり、クライアントとは何の関連もなく、常に同じビジネスプロセスを実行します。単一のメソッドが呼び出されるだけの場合もあります。ステートレスセッションBeanは対話型のステート情報を持ちません。ただしBean内部でのみ有効なステート情報は持つことができます。クライアントからの変更はできません。クライアントから見ると、このBeanは常に同じ状態です。EJBコンテナはこのBeanをプーリングし、再利用することができます。

    ■ステートフルセッションBean
    ステートフルセッションBeanは複数のメソッドを持つビジネスプロセスやトランザクション処理を持ちます。また、対話型ステート情報を持ちます。

    ■エンティティBean
    エンティティBeanはビジネスロジックを持ちません。データを形成します。エンティティ Beanの価値はデータベース上のデータをオブジェクトとして操作できる点にあります。これまでRDBMSで同じような機能を実現するには、その部分の処理を独自に記述する必要がありました。しかしエンティティ BeanはRDBMSのテーブルをマッピング(通常はツールを使う)するだけでコーディングを必要としません。

    ■ビーンマネージドパーシスタンス・エンティティBean
    ビーンマネージドパーシスタンスはJDBCなどを使って開発者がコーディングによってメモリ上に展開されたエンティティBeanのフィールドデータをRDBのテーブルなどに保存する方式です。この方式であれば、個々のエンティティBeanがどのようなデータ保存を行うかをすべて開発者が決めることができ、非常に柔軟なエンティティBeanを開発できます。ただし、このBeanのデータ処理プログラミングは必須となります。

    ■コンテナマネージドパーシスタンス・エンティティBean
    コンテナマネージドパーシスタンスはEJBコンテナにフィールドデータの保存をまかせます。このため、データ処理に関するプログラミングは必要ありません。このため、生産性が高いと共に再利用性も向上します。ただし、RDBへのデータ処理をEJBコンテナが自動的に行うため、柔軟な処理は制限されます。しかし、SQL文を生成するための制御文を記述できるなど、チューニングは可能です。

     以上、EJBのアーキテクチャの基本である、EJBコンテナと各種EJBの機能と特長をご紹介しました。EJBには、さらに細かな機能がありますし、もうすぐ新しい仕様「EJB 2.0」もJavaSoftから正式リリースされることでしょう。これを機に、ぜひEJBベースのシステム開発に取り組んでいただきたいと思います。また、BEAシステムズはすでにEJB 2.0仕様を採用した次世代アプリケーションサーバ「BEA WebLogic Server 6.0」のベータ版を公開しています。ぜひこの新バージョンをご活用いただいて、新しいEJBの機能や特長を少しでも早くご理解いただければと思います。

    Webアプリケーションにおけるサーバ・サイドJavaの
    効果的な利用
      前編 EJBの役割とメリット
     EJBは何のためのコンポーネントモデルか?
     コンポーネントとしての特徴
     実際はどのように利用されているのか?
     セッションBeanとエンティティBean
     EJBは高い生産性を提供するコンポーネントモデル
    後編 EJBのアーキテクチャ
     EJBの基本的なアーキテクチャ
     EJBコンテナはシステムの中核

     EJBコンテナが提供する機能

     セッションBeanとエンティティBeanの役割


    Java Agile フォーラム 新着記事
    @ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

    注目のテーマ

    Java Agile 記事ランキング

    本日 月間