Last update 2003年6月頃
エンタープライズJavaBeans、いろいろ見かけることはあるけれど、具体的になんなのか、ちょっとわからない。
そんなこんなでメモしていきたいと思います。
もくじ
企業システムの中で扱うような機能、ということで、非常に難しくなっています。J2EEの機能のひとつです。
まず、EJBには3種類あります。エンティテイBeanとセッションBean、それにメッセージ駆動型Beanです。プログラムの構成は似ていますが、システム中での役割はそれぞれ異なります。JavaBeansと似ている部分もありますが、似ているのはエンティティBeanです。他のEJBは、とりあえず別物です。
Beansとしてデータを中心に扱うという意味では、エンティテイBeanがそれに相当します。JavaBeansとの違いは、背後にデータベースなどを持っているということです。これは、企業などがデータを扱う場合に重要になってくる部分ですね。データをオブジェクトとして扱えるようにしたものがエンティティEJBです。JavaBeansであれば、保存方法は決まっていませんので、システムごとにデータベースなどに保存する方法を考えなければなりません。管理のための機能もないので検索の方法なども決まっていません。エンティティEJBであれば、そのデータ管理の部分は、プログラムとしてあまり書かなくてよいように標準化されています。同じデータに対してインスタンスを2重に作って整合性が崩れることもないようにいろいろと考えられています。JavaBeansがjava.la.ng.Objectクラスなら、EJBはjava.util.Collectionのような管理機能も追加したものか。
セッションBeanは何をするかというと、サービスを提供するものとでもいうのかな。構造はエンティティBeanより簡単で、よく使われてもいるようです。こちらは背後のエンティティBeanをまとめて操作するような機能を実装します。データベースなどとは連動しません。プロパティのようなものも持ちません。JavaBeansとも似ていないですね。なんのためにあるのかというと、リモート呼び出しでいろいろするため。
企業のシステムは、1つのマシンでまかなえるような小規模なものではないこともよくあります。EJBはそのための分散システムとして考えられています。逆に分散しない場合はデータベースの永続化に他のものを使うなどした方が効率的なこともあります。
JavaBeansは単体環境で動作するものですが、EJBはRMI-IIOPなどを使用した、複数プロセスでの分散を想定していたりします。
ビジネスメソッドなどの実装という点では同じ。RMIを使ってJavaBeans的なビジネス機能、データベース的機能を複数環境に分散させようという仕組み。
というわけで、EJBは分散(リモート呼び出し)機能と管理機能を持ったBeanですね。
エcタープライズBeanという言い方もあるようです。
EJBのServlet/JSPとの関連は? J2EEの構成のなかでは、EJBはビジネス層という部分に相当し、Servletなどからデータベースのデータをただのデータではなくビジネス的な機能として簡単に扱えるようにするものです。Servlet/JSPとは別のサーバ(EJBコンテナ)で動きます。分散して配置することもできます。Servletなどとは別のものとして考えてよいです。EJBにはセッションBeanとエンティティーBeanの2つの種類があるので、その役割は少しずつ違うようです。
目的は、ビジネスロジックの部品化による、再利用性を高めること。
J2EEの構成要素かな? J2EEより先にEJBを知っておきましょう。
J2EEの中心的な存在(のように思われることが多い?)ではありますが、J2EEを使うのには必ずEJBが効果的、というわけでもないようです。使わない方が楽・・・なのかも・・・。
EJBにも、Servlet / JSP の実行環境であるTomcat/JRunなどと同じように、実行環境が必要です。
Tomcat
は、Webコンテナで、その上で動くのがWebアプリケーションなのですが、EJBもこれとおなじで、EJBサーバ、EJBコンテナとEJBコンポーネントなどという説明がされているものが多いのです。
実行時構成
ファイル構成
EJBサーバは、各種Webアプリケーションサーバなどと呼ばれる製品です。J2EEのEJBサーバを持っています。
EJBサーバ内で、EJBが動作します。そのとき、中間にEJBコンテナという物があります。EJBコンテナは、EJBサーバ内でEJBから自動的に生成され?、EJBコンテナがクライアントなどとのやりとりをします。EJBは外から直接みることはできません。まぁ、このへんはあまり気にしなくてもいいのかもしれません。
どうやって外部から呼び出すのかというと、EJBはEJBサーバによってJNDI に名前付きで登録されるので、JNDI を使って他のEJBやServletなどから呼び出して使います。
| 名 | どこにある? | どんなもの |
|---|---|---|
| EJBコンポーネント | 開発者が作る | ビジネスロジック |
| EJBコンテナ | EJBサーバにより一部EJBから自動生成される? | 管理層。トランザクション処理、DBとの同期、クライアントとの通信などをする |
| EJBサーバ | J2EEなど | 実行環境 |
まず環境をそろえたいのでEJBサーバはどのようなものがあるのでしょう? J2EE環境しかないのでしょうか?
J2EEの一部なので、J2EEに対応した環境が必要なようです。Tomcat のようなEJBのみの環境はないかもしれません。Sunから、Sun ONE
Application Server 7というのがリリースされているようです。これもJ2EEと同じく無料で利用できるようなので、試してみてもいいかもしれません。
Servlet/JSPと同様、サーバで動作するフレームワーク的なものです。
J2EEの環境に、EJBサーバが含まれています。
EJBは、複数のサーバに分散させて配置することができるようです。リモートからも、EJBのクライアント用のAPIを使うことができます。これはRMI-IIOP、CORBA的なプロトコルを使って実現しているようです。
エンティティBeanとセッションBeanがある。 セッションBeanのちょっと違うものにはメッセージ駆動型Beanもある。
エンティティBeanは、DBのテーブルまで自動生成してくれるものもあるらしい。
Servlet/JSPなどと違い、配備記述子によって自動配備が可能。削除もできる。
複数インスタンスと、それらを管理する管理機能のような構造をしている。
| びーんの種類 | どんなかな? | 対応バージョン |
|---|---|---|
| セッションBean | ユーザサイドのセッション情報を扱うBeanかな? ビジネスロジックとかいうものはこっちでまとめて作るらしいです。 ステートフル、ステートレスの2種類がある。 |
EJB1.0 |
| エンティティBean | データベースなどに蓄積した情報をオブジェクトとして扱うためのBeanかな? JDBCで代用もできなくもない。 CMPとBMPのふたつがあるみたい。配備のところの難易度、非常に高め。 |
EJB1.0オプション (1.1以降必須) |
| メッセージ駆動型Bean | JMSのイベントの受信を担当する。エンティティBeanやセッションBeanを呼び出さないと、それ自体では何もできないのでEJBクライアントに相当する? JMS使うときに調べればいいです。 | EJB2.0 |
対応バージョンの順に、SessionBean、EntityBeanの順でみてみけばいいのかな。エンティティBeanは難しいので、無理せずセッションBeanだけ使いましょうか。
これらいろいろは、J2EE環境のEJBコンテナの中で動作する。
各種Enterprise JavaBeanは、ホームインターフェース、コンポーネント(リモート)インターフェース、実体クラス、配備記述子のセットで作られます。また、EJB2.0でリモートではなく同一環境内限定で使うEJBには、ローカルホームインターフェース、ローカルインターフェースも使えるようです。
インターフェースは、Javaのインターフェースというより、C言語のヘッダファイルのようなわかりにくいような存在ですね。
エンタープライズBean |
セッションBean | エンティテイBean | どんな? | ||
|---|---|---|---|---|---|
| クラス/Interface名 | 区別 | ステートフル | ステートレス | CMP/BMP | |
| Homeインターフェース ***Home Local***Home |
クラス | javax.ejb.EJBHome javax.ejb.EJBLocalHome |
管理用インターフェース | ||
| メソッド | create(...) |
create() | create(...) find***(...) remove |
||
コンポーネントインターフェース |
クラス | javax.ejb.EJBObject javax.ejb.EJBLocalObject |
ビジネスメソッドなど用 インターフェース | ||
| メソッド | ビジネスメソッド |
||||
| エンタープライズBean ***Bean |
クラス | javax.ejb.SessionBean | javax.ejb.EntityBean | EJB本体クラス | |
| メソッド | ejbCreate(...) |
ejbCreate() ビジネスメソッド |
ejbCreate(...) ejbFind***(...) ビジネスメソッド |
||
| 配備記述子(DD) | XML? | DBとの対応 | |||
使う側から見れば、どれも似たようなものかもしれません。作る場合には、違いを熟知しておきましょう。
まずセッションBeanとエンティティーBeanの違いについて知っておくのがよいでせぅか、リモートとかホームとかの違いからか、どっちでも好きな方からみてください。
Enterprise JavaBeansは、メインとなるクラスとリモートから制御するための2つのインターフェースから成ります。それぞれ、クラス名の付け方があるようです。たとえば、SampleBeanには、Sample リモートインターフェースとSampleHome ホームインターフェースがあり、全体をSampleEJBといいます。
インターフェースは、リモートから制御するために作られたようですね。なんとなくC言語のヘッダファイルみたいで面倒な感じです。
まず、メインになるのは各エンタープライズBeanクラスです。これに機能が組み込まれます。クラス名にはBeanを付けます。
ビジネスメソッドや管理機能を使うために、以下の各種インターフェースを用意します。
は、各種インスタンスの管理をするためのマネージャー的なリモートインターフェースです。これを使って、遠隔からEJBを作ったり(create)、存在しているもののなかから検索したり(find)します。ここで定義したメソッドは、エンタープライズBeanのejbCreate()などの前にejbを付けたメソッドに関連づけられます。EJBの種類ごとに基本的なメソッド名と役割が決まっています。ホームインターフェース自体は、RMIの機能? JNDIかな、を使ってクライアントから使えるような感じです。
ローカルホームインターフェースは、RMIを使いません。単体サーバ内で呼び出すときにだけ使えます。用途に合わせてどちらかを用意します。両方あってもいいようです。
リモートからエンタープライズBeanにアクセスするためのビジネスメソッド(使うためのメソッド)を定義したインターフェースです。RMI的です。使うときにクライアント側から見えるのはこのインターフェースなので***Beanや***Homeという名前にはなっていません。
大抵はツールで自動生成のようです。気にしない・・・・? 配備記述子は、複数の段階を経て作られます。
ひととおり見てみれば、クラスやインターフェースがごちゃごちゃしていますが、とりあえず中心的なエンタープライズBeanのクラスを作ればいいということがわかると思います。インターフェースの類は、最初の方で出てきたEJBコンテナの外側で使われるのですね。
作ってみると、ローカルインターフェースでアクセスできるのは、どこまでの範囲なのか? というちょっとした疑問があります。
詳細は[J2EE]のJNDIの項目を見てほしいのですが、参照名とEJB名を配備記述子で対応させ、そこからJNDI名を使わずに対応できる範囲で使えます。さて、その範囲がどこまでかというと、Sun ONE Application Server 7では、1つの配備用のアーカイブファイルの中という位置づけのようです。WARとEJB-JARを別々に配備した場合にはWARからEJBは参照できません。たぶん。EAR形式で1つにまとめて配備すると、ローカルEJBとしてアクセスすることができます。
J2EEアプリケーション設計ガイドなどにも書かれていますが、試してみたところではそんな感じでした。
エンティティBeanとセッションBeanの違いは、データベースリソースに関連しているかいないかです。Beanや情報に相当する機能がエンティテイBeanで、利用者によってエンティティBeanにアクセスする手段を制限しながら特定の機能を実現するのがセッションBeanです。ビジネスロジックといわれているのは、まぁ、いろいろな要素を組み合わせながら行う各種「手続き」です。たとえば、J2EEのサンプルとしてあるチケット予約などの場合には、チケットや利用者にあたる部分はエンティテイBean、予約手続き、ユーザの登録情報の変更などはセッションBeanとして実装します。たぶん。
状態が保証されない? 名前そのままで、Webショップの買い物篭的な、ユーザ単位でセッションを扱ったりするのがステートフルなセッションBeanなのです。Servletのセッション管理機能をビジネスロジック側に分離する形で実装したもの、というと簡単すぎるでしょうか。
javax.ejb.SessionBean
ステートレスセッションBeanは、複数のクライアントを相手にしたりすることができるなどの利点がある反面、いつ再生成されるかはわかりません。常に再生成されるかもしれません。createメソッドにパラメータを持ちません。staticメソッド的な利用方法に限定して、値を保存することも避けた方がよいです。
メソッド
JavaBeansと同じように、主にデータを格納する。データベース(DB)の1つの行に格納されている持続的なデータを示すとか相当するようなもの。データベースに限ったわけではないが、そのほとんどはデータベースのような永続的な記憶と呼ばれるものと対応している。 EJBのget / put は、メモリ内のオブジェクトではなく、データベースとのやりとりが発生すると思っておけばいいようだ。これで、サーバが停止してもデータはデータベースに残るので、これを永続化などという。
エンティティBeanには、CMPエンティティBeanとBMPエンティティBeanなるものに分けることができ、CMPはEJBコンテナにより自動で永続化(ファイルやデータベースとの対応)の処理がされる。BMPは開発者が永続化のコードを記述する。CMPを使うのが理想的だが、CMPは単一のテーブルしか参照できないため、複雑なデータベースとの連携をする場合などにはBMPエンティティBeanを利用することになる。(EJB2.0ではそうではなくなっている?)
どちらかというと、作るのはCMPエンティティBeanの方が簡単かもしれないが、どのように配備されるか、DBと関連づけはどうなる? というのを気にすると、CMPエンティティBeanの方が慣れるまでは格段に難解なような気がする。
CMPには、EJB1.1の形式と、EJB2.0の形式の2つがある。
エンティティBeanは、今のところデータベースと似たようなものなので、データベースの説明をすればわかりやすいのかもしれない。ホームインターフェースに、各種SQL的な機能がそろってます。
findやcreateメソッドは、複数種類作ることができます。
primary key 的なオブジェクト(Stringなど)を使ってインスタンスを特定します。
インスタンスが特定できれば、コンポーネントインターフェース側のビジネスメソッドやset/get を使って、update、select 相当のことができます。複数インスタンスに対してのselectやupdate相当の機能はないかもしれません。
RDBMSでは、リレーションできますが、EJBではどうするのでしょう。
CMRという設定をすることで、リレーションを設定することができます。
SQLの外部参照とかのようなもの?
EJB QLだったか、そんな感じのSQLのような仕組みがあるようです。CMRとは関係ない?
EJB QLは、検索メソッド( find~() )と関連して配備記述子に設定します。
エンティティBeanは、セッションBeanから利用するという場面が一番多いです。その他はほとんどありません。たぶん。
FAQ?
Q. エンティティBeanには必ずprimary keyが必要か?
A. 必ず必要というわけでもない? null にすればいいのか?
Q. primary keyとなるシリアル番号の生成はどうすればいいか?
A.
Q. JNDIはどのようなときに使うのか
A. ローカルまたはリモートからEJBを参照するとき。
下の方参照
各種処理はセッションBeanで実装しますが、エンティティBeanは、単純なアクセサとなるメソッドだけを用意しておけばよいのでしょうか?
JMSからのメッセージによって動作するEJB。どちらかというと、Servletのようなものか?と予測してみる。これは、EJBというよりJMSの部類のようなので、各EJB本でも扱っていませんね。他のEJBのようないろんなインターフェースがありません。とりあえず知らなくてもいいです。
作る前に、どのように組み合わせて使うのがよいのかみておきましょう。
クライアント - セッションBean - エンティティBean - EIS(データベースなど)
またはWeb Servlet
こんな感じになります。クライアント環境から見えるのはセッションBeanです。エンティティBeanはセッションBeanのビジネスロジックから利用するようです。エンティティBeanは、CMPエンティティBeanを使えばいいのかもしれませんが、エンティティBeanよりJDBCなどを使った方がいいこともあるとかないとか。
とりあえず、ServletなどからエンティティBeanを使うことはないので、エンティティBeanはローカルインターフェースのみ、セッションBeanもWebと同じサーバで実行するのならローカルインターフェースのみでいいようです。
ツールを使います。使わないと、面倒で作れません。J2EEチュートリアルを見てみれば、J2EEのツールを使って作ることもできるようです。Sun ONE Studio 5, Standard Editionなど、各種J2EE対応のツールを使うと楽なのかもしれません。たぶん。どちらにしても、最初に各EJBの違いを知っておいてから作らないと作れません。エンタープライズアプリケーションとEJBの組み合わせが面倒・・・か?
Enterprise Editionで、メニューから選択して作れます。
アプリケーション設計ガイドなどだけでは個々の開発ツールについては触れられていないので、Sun ONE Studio のEJBチュートリアルを読んでおくのがおすすめかもしれません?
セッションBeanとかエンティティーBeanとか、CMPとかBMPとか、違いを理解した上で進めましょう。インターフェースは、とりあえず分散しないのでLocalを選択すればいいようです。エンティティBeanを作る場合は、データベースのテーブルを元にして作ることができます。先にテーブルを用意してからエンティティBeanを作るようにしませう。
PostgreSQL JDBCドライバがそのままでは、関係CMPエンティティBeanを作れないので、[PostgreSQL 7.3.3用JDBCドライバ]にしてみてください。
関係エンティティBeanというのは、外部キーを使った関係をあらわすもののようです。新規で作って、関連するtableを2つ選べば作れますが、ほかにもつくり方はいろいろあるようです。
EJBをejb-jar化し、さらにear に格納するようです。
EJBとJNDI名との対応はどこでする?
ejb-jarファイルの配備記述子で、外部に公開する名前を決めますね。あとは、外部リソースもEJBの配備記述子で指定します。
J2EE RIでは、deploytoolを使います。
Sun ONE Studio 4 EEではEJBモジュール(ejb-jarになる部分)のプロパティの項目から設定できるようです。
Sun ONE Application Serverだけでも、できるのか? J2EE的ならできるはず・・・?
EJBを作って、使うにはどうすればいいのでしょうか。まずはEJBサーバが必要です。Java 2 SDK, Enterprise Edition(J2EE)やSun ONE Application Server 7などが無料で利用できます。J2EEは開発用のみ、Sun ONEは運用にも利用できます。
JNDIがここででてくるのです。むぅ。[JNDI]とか[J2EE]みておいてください。
[しいしせねっと]