Menu Close
12.3. サービスのインポート
概要
本セクションでは、OSGi サービスレジストリーにエクスポートされた OSGi サービスへの参照を取得および使用する方法を説明します。reference 要素または reference
-list
要素のいずれかを使用して、OSGi サービスをインポートすることができます。reference
要素は、ステートレス サービスへのアクセスに適していますが、reference-list
要素は ステートフル サービスへのアクセスに適しています。
サービス参照の管理
OSGi サービス参照を取得する以下のモデルがサポートされます。
参照マネージャー
リファレンスマネージャー インスタンスは、Blueprint リファレンス
要素によって作成されます。この要素は単一のサービス参照を返し、ステートレスサービスにアクセスするための推奨されるアプローチです。図12.1「ステートレスサービスへの参照」 は、参照マネージャーを使用してステートレスサービスにアクセスするためのモデルの概要を示しています。
図12.1 ステートレスサービスへの参照

クライアントの Blueprint コンテナーの Bean は、OSGi サービスレジストリーからサービスオブジェクト (バッキングサービス) によってバッキングされるプロキシーオブジェクト (提供済みオブジェクト) にインジェクトされます。このモデルは、以下の方法で、ステートレスサービスが相互変更可能であるという事実を明示的に利用します。
-
参照要素の基準に一致する複数のサービスインスタンスが見つかると、参照
マネージャーはバッキングインスタンスとして任意の方法で選択できます(相互変更可能であるためです)。 - バッキングサービスが消えた場合、参照マネージャーは、同じタイプの他の利用可能なサービスの 1 つを使用するようにすぐに切り替えることができます。したがって、あるメソッド呼び出しから次のメソッド呼び出しまで、プロキシが同じバッキングサービスへの接続を維持する保証はありません。
したがって、クライアントとバッキングサービス間のコントラクトはステートレスであり、クライアントは常に同じサービスインスタンスと通信していると想定してはなりません。一致するサービスインスタンスが利用できない場合、プロキシーは ServiceUnavailable
例外をスローする前に一定の時間待機します。タイムアウトの長さは、リファレンス
要素に timeout
属性を設定することで設定可能です。
参照リストマネージャー
リファレンスリストマネージャー インスタンスは、Blueprint reference-list
要素によって作成されます。この要素はサービス参照のリストを返し、ステートフルサービスにアクセスするための推奨されるアプローチです。図12.2「ステートフルサービスへの参照のリスト」 は、参照リストマネージャーを使用してステートフルサービスにアクセスするためのモデルの概要を示しています。
図12.2 ステートフルサービスへの参照のリスト

クライアントの Blueprint コンテナーの Bean は、プロキシーオブジェクトの一覧が含まれる java.util.List
オブジェクト(提供されるオブジェクト)にインジェクトされます。各プロキシーは、OSGi サービスレジストリーの一意のサービスインスタンスによってバッキングされます。ステートレスモデルとは異なり、ここではバッキングサービスは互換性があるとは見なされません。実際、リスト内の各プロキシーのライフサイクルは、対応するバッキングサービスのライフサイクルと密接に関連しています。サービスが OSGi レジストリーに登録されると、対応するプロキシーが同期的に作成され、プロキシリストに追加されます。また、サービスが OSGi レジストリーから登録解除されると、対応するプロキシーがプロキシーリストから同期的に削除されます。
したがって、プロキシーとそのバッキングサービス間のコントラクトはステートフルであり、クライアントは、特定のプロキシーでメソッドを呼び出すときに、常に同じバッキングサービスと通信していると想定する場合があります。ただし、バッキングサービスが利用できなくなることがあり、その場合はプロキシーが古くなります。古いプロキシーでメソッドを呼び出すと、ServiceUnavailable
例外が生成されます。
インターフェースによるマッチング (ステートレス)
stateles サービス参照を取得する最も簡単な方法は、リファレンス
要素の interface
属性を使用して、一致するインターフェースを指定することです。インターフェース
属性値がサービスのスーパータイプである場合や、属性値がサービスによって実装された Java インターフェースである場合(interface 属性は Java クラスまたは Java インターフェース
のいずれかを指定できます)、一致すると見なされます。
たとえば、ステートレスの SavingsAccount
サービスを参照するには( 例12.1「単一のインターフェースを使用したサンプルサービスのエクスポート」を参照)、以下のように 参照
要素を定義します。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <reference id="savingsRef" interface="org.fusesource.example.SavingsAccount"/> <bean id="client" class="org.fusesource.example.client.Client"> <property name="savingsAccount" ref="savingsRef"/> </bean> </blueprint>
参照
要素によって ID が savingsRef
のリファレンスマネージャー Bean が作成されます。参照されるサービスを使用するには、以下のように savingsRef
Bean をクライアントクラスのいずれかに挿入します。
クライアントクラスにインジェクトされた bean プロパティーは、Savings Account
から割り当て可能なタイプにすることができます。たとえば、以下のように Client
クラスを定義できます。
package org.fusesource.example.client; import org.fusesource.example.SavingsAccount; public class Client { SavingsAccount savingsAccount; // Bean properties public SavingsAccount getSavingsAccount() { return savingsAccount; } public void setSavingsAccount(SavingsAccount savingsAccount) { this.savingsAccount = savingsAccount; } ... }
インターフェースによるマッチング (ステートフル)
reference -list
要素の interface
属性を使用して、一致するインターフェースを指定することが最も簡単な方法です。次に、リファレンスリストマネージャーはすべてのサービスのリストを取得します。interface
属性値はサービスのスーパータイプまたはサービスによって実装された Java インターフェースのいずれかになります( interface
属性は Java クラスまたは Java インターフェースのいずれかを指定できます)。
たとえば、ステートフルな SavingsAccount
サービスを参照するには( 例12.1「単一のインターフェースを使用したサンプルサービスのエクスポート」を参照)、以下のように reference-list
要素を定義します。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <reference-list id="savingsListRef" interface="org.fusesource.example.SavingsAccount"/> <bean id="client" class="org.fusesource.example.client.Client"> <property name="savingsAccountList" ref="savingsListRef"/> </bean> </blueprint>
reference-list
要素は、ID が savingsListRef
で参照リストマネージャー Bean を作成します。参照されるサービスリストを使用するには、以下のように savingsListRef
Bean 参照をクライアントクラスのいずれかに挿入します。
デフォルトでは、savingsAccountList
bean プロパティーはサービスオブジェクトのリストです(例: java.util.List<SavingsAccount>
)。以下のようにクライアントクラスを定義できます。
package org.fusesource.example.client; import org.fusesource.example.SavingsAccount; public class Client { java.util.List<SavingsAccount> accountList; // Bean properties public java.util.List<SavingsAccount> getSavingsAccountList() { return accountList; } public void setSavingsAccountList( java.util.List<SavingsAccount> accountList ) { this.accountList = accountList; } ... }
インターフェースおよびコンポーネント名によるマッチング
ステートレス サービスのインターフェース名とコンポーネント名(bean ID)の両方に一致するには、以下のように reference
要素の interface
属性と component-name
属性の両方を指定します。
<reference id="savingsRef" interface="org.fusesource.example.SavingsAccount" component-name="savings"/>
ステートフル サービスのインターフェースとコンポーネント名(bean ID)の両方に一致するには、以下のように reference
属性の両方を指定します。
-list 要素の
nameinterface
属性と component-
<reference-list id="savingsRef" interface="org.fusesource.example.SavingsAccount" component-name="savings"/>
サービスプロパティーとフィルターの一致
フィルターに対してサービスプロパティーを一致することにより、サービスを選択できます。フィルターは、リファレンス要素または reference
-list
要素で filter
属性を使用して指定されます。フィルター
属性の値は LDAP フィルター式 である必要があります。たとえば、bank .name
サービスプロパティーが HighStreetBank
と等しい場合にマッチするフィルターを定義するには、以下の LDAP フィルター式を使用できます。
(bank.name=HighStreetBank)
2 つのサービスプロパティー値に一致させるには &
together を使用し、式を論理 と
組み合わせます。たとえば、foo プロパティーが
FooValue
と同等で、bar
プロパティーが BarValue
と同等で、以下の LDAP フィルター式を使用できます。
(&(foo=FooValue)(bar=BarValue))
LDAP フィルター式の完全な構文は、OSGi Core Specification のセクション 3.2.7 を参照してください。
フィルターは、インターフェースと
コンポーネント名の設定と組み合わせることもできます。この場合は、
指定した条件をすべて一致させる必要があります。
たとえば、Savings Account
タイプの ステートレス サービスに一致し、HighStreetBank
と同等の bank .name
サービスプロパティーを使用する場合は、以下のように 参照
要素を定義します。
<reference id="savingsRef" interface="org.fusesource.example.SavingsAccount" filter="(bank.name=HighStreetBank)"/>
SavingsAccount
タイプの ステートフル サービスに一致し、HighStreetBank
と同等の bank .name
サービスプロパティーで、以下のように reference-list
要素を定義します。
<reference-list id="savingsRef" interface="org.fusesource.example.SavingsAccount" filter="(bank.name=HighStreetBank)"/>
必須または任意であるかの指定
デフォルトでは、OSGi サービスへの参照は必須であると想定されます (必須の依存関係を参照)。要素に availability
属性を設定して、参照
要素または参照 リスト
要素の依存関係の動作をカスタマイズできます。
availability
属性の値は 2 つあります。
-
必須
(デフォルト)は、通常の Blueprint コンテナーの初期化中に依存関係を解決する 必要がある ことを意味します。 -
任意
。これは、初期化中に依存関係を解決する 必要がない ことを意味します。
以下の 参照
要素の例は、参照が必須な依存関係であることを明示的に宣言する方法を示しています。
<reference id="savingsRef" interface="org.fusesource.example.SavingsAccount" availability="mandatory"/>
参照リスナーの指定
OSGi 環境の動的な性質に対応するため、オプションの
availability-it に宣言したサービス参照の一部が、バッキングサービスがレジストリーにバインドされている場合、またレジストリーからバインドされないタイミングを追跡する場合に便利です。サービスバインディングおよびバインド解除イベントの通知を受け取るには、reference -listener 要素を reference
要素または reference
-list
要素の子として定義できます。
たとえば、以下の Blueprint 設定では、ID で参照リスナーをリファレンスマネージャーの子として savingsRef
を使用して定義する方法を示しています。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <reference id="savingsRef" interface="org.fusesource.example.SavingsAccount" > <reference-listener bind-method="onBind" unbind-method="onUnbind"> <bean class="org.fusesource.example.client.Listener"/> </reference-listener> </reference> <bean id="client" class="org.fusesource.example.client.Client"> <property name="savingsAcc" ref="savingsRef"/> </bean> </blueprint>
上記の設定では、バインドおよびバインド解除
イベントをリッスンするコールバックとして
org.fusesource.example.client.Listener
タイプのインスタンスを登録します。イベントは、savingsRef
参照マネージャーのバッキングサービスがバインドまたはバインド解除されるたびに生成されます。
以下の例は、Listener
クラスの実装例を示しています。
package org.fusesource.example.client; import org.osgi.framework.ServiceReference; public class Listener { public void onBind(ServiceReference ref) { System.out.println("Bound service: " + ref); } public void onUnbind(ServiceReference ref) { System.out.println("Unbound service: " + ref); } }
メソッド名 のBind
および onUnbind は、bind
-method
属性と unbind-method 属性によって指定され
ます。これらのコールバックメソッドはいずれも org.osgi.framework.ServiceReference
引数を取ります。