12.2. サービスのエクスポート
概要
このセクションでは、Java オブジェクトを OSGi サービスレジストリーにエクスポートして、OSGi コンテナー内の他のバンドルからサービスとしてアクセスできるようにする方法について説明します。
単一のインターフェイスでのエクスポート
単一のインターフェイス名で OSGi サービスレジストリーにサービスをエクスポートするには、ref 属性を使用して関連するサービス Bean を参照する service 要素を定義し、interface 属性を使用してパブリッシュされたインターフェイスを指定します。
たとえば、例12.1「単一のインターフェイスを使用したサンプルサービスのエクスポート」 に記載されている Blueprint 設定コードを使用して、org.fusesource.example.Account インターフェイス名の下にある SavingsAccountImpl クラスのインスタンスをエクスポートできます。
例12.1 単一のインターフェイスを使用したサンプルサービスのエクスポート
ref 属性は、対応する Bean インスタンスの ID を指定し、interface 属性は OSGi サービスレジストリーに登録されているパブリック Java インターフェイスの名前を指定します。この例で使用されているクラスとインターフェイスは、例12.2「サンプルアカウントクラスとインターフェイス」 に示します。
例12.2 サンプルアカウントクラスとインターフェイス
複数のインターフェイスを使用したエクスポート
複数のインターフェイス名の下にある OSGi サービスレジストリーにサービスをエクスポートするには、ref 属性を使用して関連するサービス Bean を参照する service 要素を定義し、interfaces 子要素を使用してパブリッシュされたインターフェイスを指定します。
たとえば、次の Blueprint 設定コードを使用して、パブリック Java インターフェイス org.fusesource.example.Account および org.fusesource.example.SavingsAccount のリストの下にある SavingsAccountImpl クラスのインスタンスをエクスポートできます。
interface 属性と interfaces 要素は、同じ service 要素で同時に使用できません。どちらか一方を使用する必要があります。
自動エクスポートによるエクスポート
実装されたすべてのパブリック Java インターフェイス下で、サービスを OSGi サービスレジストリーにエクスポートする場合には、auto-export 属性を使用してこれを簡単に実現する方法があります。
たとえば、実装されたすべてのパブリックインターフェイスで SavingsAccountImpl クラスのインスタンスをエクスポートするには、以下の Blueprint 設定コードを使用します。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/> <service ref="savings" auto-export="interfaces"/> ... </blueprint>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/>
<service ref="savings" auto-export="interfaces"/>
...
</blueprint>
auto-export 属性の値 interfaces は、Blueprint が SavingsAccountImpl によって実装されたすべてのパブリックインターフェイスを登録する必要があることを示しています。auto-export 属性には、次の有効な値を指定できます。
disabled- 自動エクスポートを無効にします。これはデフォルトになります。
interfaces- 実装されているすべてのパブリック Java インターフェイスにサービスを登録します。
class-hierarchy-
Objectクラスを除き、独自のタイプ (クラス) およびすべてのスーパータイプ (スーパークラス) の下のサービスを登録します。 all-classes-
class-hierarchyオプションと同様ですが、実装されたすべてのパブリック Java インターフェイスも含まれます。
サービスプロパティーの設定
OSGi サービスレジストリーを使用すると、サービス プロパティー を登録済みサービスに関連付けることもできます。その後、サービスのクライアントは、サービスプロパティーを使用して、サービスを検索またはフィルターリングできます。サービスプロパティーをエクスポートしたサービスに関連付けるには、1 つ以上の beans:entry 要素が含まれる service-properties 子要素を追加します (サービスプロパティーごとに beans:entry 要素 1 つ)。
たとえば、bank.name 文字列プロパティーを普通預金口座サービスに関連付けるには、以下の Blueprint 設定を使用できます。
bank.name 文字列プロパティーの値が HighStreetBank の場合。文字列以外のタイプのサービスプロパティーを定義することができ、プリミティブタイプ、配列、およびコレクションもサポートされます。これらのタイプを定義する方法は、Spring Reference Guide の アドバタイズされたプロパティーのセットの制御 を参照してください。
entry 要素は Blueprint namespace に属している必要があります。Spring の Blueprint 実装での beans:entry 要素の使用は標準ではありません。
デフォルトのサービスプロパティー
以下のように、service 要素を使用してサービスをエクスポートするときに自動的に設定される可能性がある 2 つのサービスプロパティーがあります。
-
osgi.service.blueprint.compnameは、Bean がインライン (Bean がservice要素の子要素として定義される) の場合を除き、サービスのbean要素のidを常に設定します。インライン化された Bean は常に匿名です。 -
service.rankingは、ranking 属性がゼロ以外である場合に自動的に設定されます。
ランキング属性の指定
バンドルがサービスレジストリーでサービスを検索し、一致するサービスが複数見つかった場合は、ランキングを使用して、どのサービスが返されるかを判断できます。このルールは、ルックアップが複数のサービスに一致する場合は常に、最高ランクのサービスが返されるというものです。サービスランクは負ではない整数で、0 がデフォルトです。service 要素に ranking 属性を設定して、サービスランクを指定できます。以下に例を示します。
<service ref="savings" interface="org.fusesource.example.Account" ranking="10"/>
<service ref="savings" interface="org.fusesource.example.Account" ranking="10"/>
登録リスナーの指定
サービスの登録および登録解除イベントを追跡する場合は、登録および登録解除イベント通知を受信する 登録リスナー コールバック Bean を定義できます。登録リスナーを定義するには、registration-listener 子要素を service 要素に追加します。
たとえば、以下の Blueprint 設定は、registration-listener 要素によって参照されるリスナー Bean listenerBean を定義し、Account サービスが登録または登録解除されるたびにリスナー Bean がコールバックを受信するようにします。
registration-listener 要素の ref 属性がリスナー Bean の id を参照する場合は、registration-method 属性は登録コールバックを受信するリスナーメソッドの名前を指定し、unregistration-method 属性は登録解除コールバックを受信するリスナーメソッドの名前を指定します。
以下の Java コードは、登録および登録解除のイベントの通知を受信する Listener クラスの定義例を示しています。
メソッド名 register および unregister は、それぞれ registration-method 属性および unregistration-method 属性によって指定されます。これらのメソッドの署名は、次の構文に準拠している必要があります。
-
最初のメソッド引数: サービスオブジェクトのタイプから割り当て可能な任意のタイプ T。つまり、サービスクラスのスーパータイプクラス、またはサービスクラスによって実装されるインターフェイス。サービス Bean が
scopeがprototypeであることを宣言していない限り、この引数にはサービスインスタンスが含まれます。この場合、この引数はnullです (スコープがprototypeの場合、登録時に利用可能なサービスインスタンスはありません)。 -
第二の方法引数は、
java.util.Map型やjava.util.Dictionary型のいずれかである必要があります。このマップには、このサービス登録に関連付けられたサービスプロパティーが含まれています。