12.2. サービスのエクスポート
概要
このセクションでは、Java オブジェクトを OSGi サービスレジストリーにエクスポートして、OSGi コンテナー内の他のバンドルからサービスとしてアクセスできるようにする方法について説明します。
単一のインターフェイスでのエクスポート
単一のインターフェイス名で OSGi サービスレジストリーにサービスをエクスポートするには、ref
属性を使用して関連するサービス Bean を参照する service
要素を定義し、interface
属性を使用してパブリッシュされたインターフェイスを指定します。
たとえば、例12.1「単一のインターフェイスを使用したサンプルサービスのエクスポート」 に記載されている Blueprint 設定コードを使用して、org.fusesource.example.Account
インターフェイス名の下にある SavingsAccountImpl
クラスのインスタンスをエクスポートできます。
例12.1 単一のインターフェイスを使用したサンプルサービスのエクスポート
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/>
<service ref="savings" interface="org.fusesource.example.Account"/>
</blueprint>
ref
属性は、対応する Bean インスタンスの ID を指定し、interface
属性は OSGi サービスレジストリーに登録されているパブリック Java インターフェイスの名前を指定します。この例で使用されているクラスとインターフェイスは、例12.2「サンプルアカウントクラスとインターフェイス」 に示します。
例12.2 サンプルアカウントクラスとインターフェイス
package org.fusesource.example public interface Account { ... } public interface SavingsAccount { ... } public interface CheckingAccount { ... } public class SavingsAccountImpl implements SavingsAccount { ... } public class CheckingAccountImpl implements CheckingAccount { ... }
複数のインターフェイスを使用したエクスポート
複数のインターフェイス名の下にある OSGi サービスレジストリーにサービスをエクスポートするには、ref
属性を使用して関連するサービス Bean を参照する service
要素を定義し、interfaces
子要素を使用してパブリッシュされたインターフェイスを指定します。
たとえば、次の Blueprint 設定コードを使用して、パブリック Java インターフェイス org.fusesource.example.Account
および org.fusesource.example.SavingsAccount
のリストの下にある SavingsAccountImpl
クラスのインスタンスをエクスポートできます。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <bean id="savings" class="org.fusesource.example.SavingsAccountImpl"/> <service ref="savings"> <interfaces> <value>org.fusesource.example.Account</value> <value>org.fusesource.example.SavingsAccount</value> </interfaces> </service> ... </blueprint>
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>
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 設定を使用できます。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:beans="http://www.springframework.org/schema/beans" ...> ... <service ref="savings" auto-export="interfaces"> <service-properties> <beans:entry key="bank.name" value="HighStreetBank"/> </service-properties> </service> ... </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"/>
登録リスナーの指定
サービスの登録および登録解除イベントを追跡する場合は、登録および登録解除イベント通知を受信する 登録リスナー コールバック Bean を定義できます。登録リスナーを定義するには、registration-listener
子要素を service
要素に追加します。
たとえば、以下の Blueprint 設定は、registration-listener
要素によって参照されるリスナー Bean listenerBean
を定義し、Account
サービスが登録または登録解除されるたびにリスナー Bean がコールバックを受信するようにします。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" ...> ... <bean id="listenerBean" class="org.fusesource.example.Listener"/> <service ref="savings" auto-export="interfaces"> <registration-listener ref="listenerBean" registration-method="register" unregistration-method="unregister"/> </service> ... </blueprint>
registration-listener
要素の ref
属性がリスナー Bean の id
を参照する場合は、registration-method
属性は登録コールバックを受信するリスナーメソッドの名前を指定し、unregistration-method
属性は登録解除コールバックを受信するリスナーメソッドの名前を指定します。
以下の Java コードは、登録および登録解除のイベントの通知を受信する Listener
クラスの定義例を示しています。
package org.fusesource.example; public class Listener { public void register(Account service, java.util.Map serviceProperties) { ... } public void unregister(Account service, java.util.Map serviceProperties) { ... } }
メソッド名 register
および unregister
は、それぞれ registration-method
属性および unregistration-method
属性によって指定されます。これらのメソッドの署名は、次の構文に準拠している必要があります。
-
最初のメソッド引数: サービスオブジェクトのタイプから割り当て可能な任意のタイプ T。つまり、サービスクラスのスーパータイプクラス、またはサービスクラスによって実装されるインターフェイス。サービス Bean が
scope
がprototype
であることを宣言していない限り、この引数にはサービスインスタンスが含まれます。この場合、この引数はnull
です (スコープがprototype
の場合、登録時に利用可能なサービスインスタンスはありません)。 -
第二の方法引数は、
java.util.Map
型やjava.util.Dictionary
型のいずれかである必要があります。このマップには、このサービス登録に関連付けられたサービスプロパティーが含まれています。