サーバアプリケーションは、Servant(インタフェース実装部)のインスタンスの管理方法により以下の4つの形態をとることができます。
以下のように要件によりアプリケーション形態を選択してください。
各クライアントが同一のServantオブジェクトを使用する方式です。つまり、クライアントごとのインスタンス管理をしない方式です。
各クライアントは、以下のように同一のServantのインスタンスを使用します。
クライアントごとに異なるServantオブジェクトを使用する方式です。
クライアントごとのインスタンス管理をPOAオブジェクトで行う方式です。Factory内で、オブジェクトリファレンスおよびインスタンスを作成します。
クライアントごとに異なるServantオブジェクトを使用する方式です。
クライアントごとのインスタンス管理をPOAオブジェクトで行う方式です。Factory内でオブジェクトリファレンスを作成し、リクエスト受信時にServantManagerオブジェクト内でインスタンスを作成します。
Factoryは、リクエストごとにオブジェクトリファレンスやインスタンスを作成するオブジェクトであり、インスタンス管理を行う場合に必要となるオブジェクトです。
AOMはActive Object Mapのことであり、インスタンスの管理テーブルのことです。
AOM、ServantManagerなどの詳細については、“5.13 サーバアプリケーションのプログラミング(POA概要)”を参照してください。
Factory-1方式およびFactory-2方式の各クライアントは、以下のように、クライアントごとに異なるServantのインスタンスを使用します。
Factory-1方式とFactory-2方式の違い
Factory-1方式は、Factory内で事前にインスタンスを作成しておくことができるため、リクエストを受信した時点でインスタンスを作成するFactory-2より性能的には若干優れます。
Factory-2方式は、リクエストを受信した時点でインスタンスを作成するため、Factory内で事前のインスタンスを作成しておくFactory-1より資源的には若干優れます。
インスタンス管理をユーザの作成するServantManagerオブジェクトに任せる方式です。
各クライアントは、以下のように、クライアントごとに異なるServantのインスタンスを使用します。インスタンスは、ユーザの作成したServantManagerオブジェクト内のインスタンス管理テーブルで行われます。
アプリケーション形態の選択
アプリケーション形態は、Servantオブジェクトの属するPOAオブジェクトのServantRetentionポリシ、RequestProcessingポリシの指定により決まります。組み合わせ方を以下に示します。詳細については、“5.13.3 POAオブジェクト”を参照してください。
アプリケーション形態 | ServantRetentionポリシ | RequestProcessingポリシ |
---|---|---|
デフォルトインスタンス方式 | NON_RETAIN | USE_DEFAULT_SERVANT |
Factory-1方式 | RETAIN | 任意 |
Factory-2方式 | RETAIN | USE_SERVANT_MANAGER |
ユーザインスタンス管理方式 | NON_RETAIN | USE_SERVANT_MANAGER |
注) 表内のポリシは、Servantオブジェクトを管理するPOAポリシに対する設定値を示しています。
Factoryについて
Factoryとは、Servantオブジェクトのインスタンスを生成し、そのオブジェクトリファレンスをクライアントに返すことを目的としたインタフェースです。
これにより、そのクライアントが専用で使用できるServantオブジェクトのインスタンスをサーバ側に持たせることが可能となります。
Factoryの概念は、以下のIDL定義によって示されます。前述したFactory-1方式、Factory-2方式を使用する際も、IDL定義で他のインタフェースとともにFactoryインタフェースを定義します。
【FactoryのIDL定義例(a)】
//何らかのインタフェース interface intf{ void op(); }; //Factoryインタフェース interface Factory { intf create(); };
上記のIDL定義で示されるように、クライアントはFactoryオブジェクトのオペレーションcreate()を発行することにより、そのクライアントで使用するintfオブジェクトを取得することが可能となります。
次に、クライアントは取得したintfオブジェクトに対し、op()オペレーションを発行することで本来の目的の処理を行います。
一方、サーバ側では、以下の一連の処理をcreate()オペレーションの実装として記述する必要があります。
Servantオブジェクト(intfインタフェースの実装クラスのインスタンス)を生成(new)します。
生成したインスタンスとオブジェクトリファレンスとの関連付けをPOAのAOMに登録します。
関連付けられたオブジェクトリファレンスを返します。
Factory-2方式では、create()オペレーションの実装として3.のオブジェクトリファレンスの生成と復帰だけを行い、1.と2.は要求時にServantManagerオブジェクト内で行います。しかし、クライアント側から見たcreate()オペレーションの機能は同じです。
Factoryとは、このようなインタフェースの機能上の概念です。したがって、IDL定義では、Factoryインタフェースの名前(上記の例:“Factory”)や実装するオペレーションの名前(上記の例:“create”)、種類は自由です。しかし、Factoryの目的上、上記のcreate()のような「戻り値としてオブジェクトリファレンスを返す」機能をもつオペレーションが最低限必要となります。
実際のアプリケーション開発では、生成したServantオブジェクトのインスタンスを解放するためのオペレーションもFactoryに実装することが推奨されます。これによりサーバ資源の節約が可能となります。
以下のIDL定義の例ではServantオブジェクトのインスタンスを解放するためのオペレーションとしてdestroy()を定義しています。
【FactoryのIDL定義例(b)】
//何らかのインタフェース interface intf{ void op(); }; //Factoryインタフェース interface Factory{ intf create(); void destroy(in intf obj); };
クライアント側では、目的の処理が終了した時点で、以前にcreate()メソッドで取得したオブジェクトリファレンスを引数としてdestroy()オペレーションをコールします。一方、サーバ側では、渡されたオブジェクトリファレンスに対応するServantオブジェクトをAOMから削除する処理を行います。
上記のIDLに対するFactoryオブジェクトのcreate()オペレーション、destoroy()オペレーションの実装例を以下に示します。ここでは、intfインタフェースの実装クラスをUserServantクラスとしています。処理の詳細については、“5.13 サーバアプリケーションのプログラミング(POA概要)”以降を参照してください。
【オペレーションの実装例(Factory-1方式)】
public intf create() { intf ior; // Servantオブジェクトのオブジェクトリファレンス try { // 1. Servantオブジェクトの生成 org.omg.PortableServer.Servant svt = new UserServant(); // 2. AOMへ登録 poa.activate_object( svt ); // 3. オブジェクトリファレンスの生成 org.omg.CORBA.Object Obj = poa.servant_to_reference( svt ); // intf型に変換 ior = intfHelper.narrow( Obj ); } catch( Exception e ) { /*例外処理*/ } return( ior ); } public void destroy( intf obj ) { try { // オブジェクトリファレンスからオブジェクトIDを求める byte oid[] = poa.reference_to_id( obj ); // Servantをdeactiveにする(AOMより削除) poa.deactivate_object( oid ); } catch( Exception e ) { /*例外処理*/ } }
注) ソース上のpoaはPOAオブジェクトのインスタンス
Factoryオブジェクトのインスタンスの扱いについて
Factoryオブジェクトのインスタンスについても、通常のServantオブジェクトのインスタンスと同様に、POAに登録します。
“5.19.2 Active Object Map(AOM)使用例(Factory-1方式)”や“5.19.3 Servant Activator使用例(Factory-2方式)”などに示した例では、Factoryオブジェクトは「Factory専用のPOA」を使用してDefault Servantとして登録しています。加えて、Factory用のPOAはAOMを使用しない設定(NON_RETAINポリシ)としています。
これは、以下の理由によるものです。
Factoryオブジェクトと、そのFactoryが生成するServantオブジェクトを、同一のPOAのAOM上で管理させることは可能です。しかし、この場合、Factoryオブジェクトへの要求に対してもAOM内の検索が行われるため、効率的ではありません。
Servantオブジェクトを管理するPOAのDefault ServantとしてFactoryオブジェクトを登録することは可能です。しかし、AOMとDefault Servantを同時に使用する場合は、Default Servantへの要求はAOMの検索の後となります。このため、Factoryオブジェクトへの要求は効率的ではありません。