第2回 Beanをうまく作るコツ
――Beanはsetしてexecuteしてgetして活用する――


EJBにするための差分

 次にリモートBeanとして働くEJBですが、このEJBにも基本的にリスト1とリスト2で紹介した業務ロジックとアクセッサをそっくりそのまま使うことができます。そういう意味では、JavaBeansもEJBも業務に関する処理についてはまったく同じものが使えることになります。このようにJavaBeansと同じ業務ロジックを動かすことができるEJBのことをSessionBeanといいます。

 しかしEJBはJavaBeansと違い、外部プログラムとBeanの間にネットワークが介在するので、外部プログラムがネットワークを介して利用できるような部分を追加する必要が出てきます。

 この追加部分もそれほども難しいものではありません。以下のリスト4のようなEJBのひな型を作成し、そこにJavaBenasで使った業務ロジックとアクセッサを記述すれば簡単です。EJBではこのひな型のことをEJB Beanと呼んでいます。

図13 外部プログラムがEJBをコールする様子

リスト4 EJB Beanの部分
 1 import java.io.*;
 2 import java.util.*;
 3 import java.sql.*;
 4
 5 import java.rmi.*;
 6 import javax.ejb.*;
 7
 8 public class TestEJBBean implements SessionBean {
 9   private String DB = new String();
10   private String TABLE = new String();
11   private String KEY = new String();
12   private String[] RESULTS = null;
13   private SessionContext my_ssc = null;
14
15 *************************
16 @業務ロジックの部分
17 *************************
18
19 *************************
20 Aアクセッサの部分
21 *************************
22
23   //アクセッサの追加
24   public void setSessionContext(SessionContext val)
25     throws RemoteException{my_ssc = val;}
26   //コールバック・メソッドの追加
27   public void ejbActivate() throws RemoteException{}
28   public void ejbCreate()
29     throws CreateException,RemoteException{}
30   public void ejbPassivate() throws RemoteException {}
31   public void ejbRemove() throws RemoteException {}
32 }
5〜6行目:EJBの作成に必要なjava.rmiとjava.ejbの2つのパッケージがインポートされます。

8行目:
このEJB Beanのクラス名はTestEJBBeanとします。このEJBは、SessionBeanになるので、SessionBeanインターフェイスをインプリメントしないといけません。

9〜12行目:
JavaBeansと同じインスタンス変数を記述します。

13行目:
EJBではコンテナがEJBの状態を保持するために必要なSessionContextプロパティを作成することが決められています。これは必ず記述しないといけないインスタンス変数です。これに対応するアクセッサが23行目にあるsetSessionContextメソッドです。このプロパティはコンテナが状態をセットするだけにしか使われないのでsetterしかありません。

15〜21行目:
JavaBeansで記述した業務メソッドとアクセッサがそのまま使える個所です。

24〜25行目:
上記の13行目の説明を参照してください。

27〜31行目:
コンテナがこのEJBに対して自動的に呼び出すメソッド群を記述しておかないといけません。このメソッドはEJBが生成されたり消滅するときに自動的にコンテナから呼び出されます。通常のSessionBeanでは、このメソッドに詳しい処理を記述しなくてもEJBとして稼働します。

 EJBの業務ロジックとアクセッサに関する個所はこれで作成されました。しかしもう1つEJBでは重要なことがあります。それはEJBを呼び出している実態は、実は外部プログラムがEJB呼び出しているというわけではなく、途中でアプリケーションサーバが介入してEJBを呼び出しているという事実です。

 簡単にいえば、EJBは外部プログラムが直接呼び出すというわけではなく、すべてアプリケーションサーバが外部プログラムに成り代わって呼び出しているということです。 EJBではこのような仕組みを採用しているおかげで、どんなアプリケーションサーバでも動かすことができますし、トランザクションやスケーラビリティ、セキュリティ制御などアプリケーションサーバの恩恵を受けることができるようになっているのです。

 このような機能を持つアプリケーションサーバをコンテナといいますが、これ以上説明するとデザインの話から離れて行ってしまうので、このあたりの詳しい話を知りたい皆さんは、このサイトのほかの先生の解説を読んでみてください。

 ここではEJBを作るときには業務ロジックやアクセッサの仕組みだけでなく、コンテナがEJBを呼び出すのに必要な情報もプログラムとして作成することが必要になってくるということを覚えておいてください。

 この必要な情報は2つあります。1つがEJBリモート・インターフェイスというひな型です。またもう1つがEJBホーム・インターフェイスというひな型です。この2つのひな型は、業務ロジックとアクセッサの入ったEJB Beanが完成していれば、これをもとにして容易に作ることができます。

 またこれらのひな型は、皆さんがEJBをコンテナに組み込むとき(この作業をデプロイなどといいます)に一緒に導入します。アプリケーションサーバはこれらのひな型を利用して外部プログラムがEJBをアクセスできるような、いろいろなネットワーク部分を自動的に作成してくれます。

 以下のリスト5がEJBリモート・インターフェイスのひな型です。これを見ると基本的に業務ロジックの記述されたメソッド名とアクセッサ名しかないことが分かりますね。

リスト5 EJBリモート・インターフェイスの部分
 1 import java.rmi.*;
 2 import javax.ejb.*;
 3
 4 public interface TestEJB extends EJBObject {
 5   void execute() throws RemoteException;
 6   void setDB(String val) throws RemoteException;
 7   String getDB() throws RemoteException;
 8   void setTABLE(String val) throws RemoteException;
 9   String getTABLE() throws RemoteException;
10   void setKEY(String val) throws RemoteException;
11   String getKEY() throws RemoteException;
12   void setRESULTS(String [] val) throws RemoteException;
13   void setRESULTS(int i,String val)throws RemoteException;
14   String[] getRESULTS() throws RemoteException;
15   String getRESULTS(int i) throws RemoteException;
16 }
4行目:EJBリモート・インターフェイスは、Javaのクラスではなくインターフェイスで作成されており、これをもとにコンテナがネットワークに必要な処理を行うプログラムを作成するひな型として使われるものです。インターフェイス名がTestEJBとなっています。必ずEJBObjectクラスを派生(エクステンド)して作成しないといけません。

5行目
業務メソッドのメソッド名を記述します。インターフェイスというのはメソッド名を記述するだけで、その中の処理を記述してはいけません。

6〜15行目:
上記と同様にアクセッサのメソッド名が記述されます。

 以下のリスト6がEJBホーム・インターフェイスのひな型に相当するものです。ここでは決めうちでcreateという名前のメソッドを入れるだけです。

リスト6 EJBホーム・インターフェイスの部分
1 import java.rmi.*;
2 import javax.ejb.*;
3
4 public interface TestEJBHome extends EJBHome {
5   TestEJB create() throws CreateException,RemoteException;
6 }
4行目:EJBホーム・インターフェイスもJavaのクラスではなくインターフェイスとして作成され、コンテナが生成するプログラムのひな型として使われます。インターフェイス名をTestEJBHomeとしました。EJBHomeクラスを派生しないといけません。

5行目:
この中には必ずcreateメソッドを記述しないといけないという決まりがあります。その戻りになる型も必ず、いま作成しているEJBリモート・インターフェイスの型(TestEJBですね)に合わせておかないといけないという決まりがあります。

(注)ここで作成したSessionBeanは外部プログラムから、set、execute、getの手順で利用されます。そのためプロパティは必ずステートフル状態で保存されていないといけません。


本当に業務ロジックがどこでも動くことができるのか

 さてこれまでの話でJavaBeansでもEJBでも、その中の業務ロジックは同じものが使えるということが分かっていただけたかと思います。ですから、皆さんがBeanを作っても、業務ロジックではJavaBeansでもEJBでも特に変わることなく意識せずに作っていい、となるわけですね。

 しかしBeanを作るということと、実際にこれを動かして使うことは、いろいろな点で違いがあります。例えば同じ業務ロジックが、どのホストコンピュータのアプリケーションサーバでも自由に動くというのはいいのですが、その業務ロジックで呼び出しているミドルソフトが、果たしてどのアプリケーションサーバにも存在しているのでしょうか? またアプリケーションサーバが動くコンピュータには、CPU性能の高いものもあれば低いものもあります。大容量のハードディスクを持っているものもあればまったくハードディスクを持たずメモリだけしか積んでいないコンピュータもあるかもしれません。

 そんなコンピュータ環境の違いの中で、その業務ロジックが多くメモリを要求したり、ハードディスクにデータを書き出したりしていいものでしょうか? 実はリスト1で解説されているexecuteメソッドもどこでも使える業務ロジックとしては問題のある個所が残っています。皆さんは気が付いたでしょうか?

 次回は、このようなコンピュータ環境の違いを頭に入れて、本当にどこでも動く、かつパフォーマンスも良くてトラブルもない部品としてBeanを作成する、業務ロジックの作成ポイントをお話ししてみたいと思います。

5/5  

 INDEX

第2回 Beanをうまく作るコツ
  今回の内容の目的  
  Beanはそれだけでは何の役にも立たない
外部プログラムとプロパティの重要な関係を知る
外部プログラムがBeanを活用する流れ
  外部プログラムとBeanのオブジェクト指向的な関係
業務処理は必ず失敗なく実行されないといけない
setterとgetterで作成される理由は?
  ローカルBeanとリモートBeanの配置の違い
JavaBeansにするための差分
  EJBにするための差分
本当に業務ロジックがどこでも動くことができるのか
  


連載記事一覧




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

注目のテーマ

Java Agile 記事ランキング

本日 月間