サービストラッカー
ご覧のページは、お客様の利便性のために一部機械翻訳されています。また、ドキュメントは頻繁に更新が加えられており、翻訳は未完成の部分が含まれることをご了承ください。最新情報は都度公開されておりますため、必ず英語版をご参照ください。翻訳に問題がある場合は、こちらまでご連絡ください。
OSGiランタイムエコシステムでは、モジュールが他のモジュールのサービスに依存して機能する方法を考慮する必要があります。 サービスの実装をスワップアウトまたは完全に削除することは可能です。また、この環境でモジュールが生き残るだけでなく繁栄する必要があります。
@Component
クラスから サービス を呼び出す場合、簡単です。別の 宣言サービス(DS) アノテーション @Reference
を使用して、サービス参照を取得します。 参照されたサービスが利用可能になると、コンポーネントがアクティブになります。
DSを使用して、 @Component
および @Reference
アノテーションを活用できる場合は、そうする必要があります。 DSは、サービスダイナミズムの処理の複雑さの多くを透過的に処理します。
DSを使用してコンポーネントを作成できない場合は、サービストラッカーを実装してサービスレジストリ内のサービスを検索する方法を学習してください。
Service Trackerを使用する必要があるシナリオは何ですか? 我々はDSのシナリオに焦点を当てている点に注意してください できません 使用すること。 これには通常、非ネイティブ(OSGiへの)依存性注入フレームワークが含まれます。
- Spring MVCポートレットからOSGiサービスを呼び出す
- OSGiサービスの呼び出し WARパッケージ化ポートレット 製品-VER @ @上で実行するようにアップグレードされていますが、ない 完全にモジュール とOSGiのモジュール化しました
OSGi以外のアプリケーションは、独自の Service Builderサービス やLiferayのモジュールで公開されているサービス(人気のある UserLocalService
)を含め、Service Trackerを使用してOSGiランタイムに登録されたサービスにアクセスできます。
Service Trackerの実装
Service Trackerでは、DSを使用してサービスの依存関係を管理することはできませんが、サービスレジストリからサービスを呼び出すことができます。
サービストラッカーは、2つの方法で実装できます。1)必要なコード内、または2) を拡張するクラス内org.osgi.util.tracker.ServiceTracker
。
直接作成するには、次を実行します。
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.osgi.util.tracker.ServiceTracker;
Bundle bundle = FrameworkUtil.getBundle(this.getClass());
BundleContext bundleContext = bundle.getBundleContext();
ServiceTracker<SomeService, SomeService> serviceTracker =
new ServiceTracker(bundleContext, SomeService.class, null);
serviceTracker.open();
SomeService someService = serviceTracker.waitForService(500);
より良い方法は、 org.osgi.util.tracker.ServiceTracker
を拡張するクラスを作成することです。これにより、コードが簡単になります。
-
ServiceTracker
を拡張するこのようなクラスを作成します。public class SomeServiceTracker extends ServiceTracker<SomeService, SomeService> { public SomeServiceTracker(Object host) { super( FrameworkUtil.getBundle(host.getClass()).getBundleContext(), SomeService.class, null); } }
-
サービスを使用するロジックの初期化部分から、サービストラッカーコンストラクターを呼び出します。
Object host
パラメーターは、独自のバンドルコンテキストを取得します。正確な結果を得るには、独自のバンドルのオブジェクトである必要があります。ServiceTracker<SomeService, SomeService> someServiceTracker = new SomeServiceTracker(this);
-
Service Trackerを使用する場合は、通常はできるだけ早く開きます。
someServiceTracker.open();
-
サービスを使用する前に、Service Trackerを使用してサービスの状態を調べます。 たとえば、プログラムロジックで、使用する前にサービスが
null
かどうかを確認します。SomeService someService = someServiceTracker.getService(); if (someService == null) { _log.warn("The required service 'SomeService' is not available."); } else { someService.doSomethingCool(); }
Service Trackerには、追跡されたサービスを内省するための他のユーティリティ機能がいくつかあります。
-
後でアプリケーションが破棄またはアンデプロイされるときに、サービストラッカーを閉じます。
someServiceTracker.close();
Service Trackerを使用すると、OSGiランタイムの外部からOSGiサービスを呼び出すことができます。
サービスのコールバックハンドラーの実装
サービスが利用できない可能性が高い場合、または複数のサービスを追跡する必要がある場合、Service Tracker APIはサービス イベントで動作するコールバックメカニズムを提供します。 これを使用するには、 ServiceTracker
の addService
および removedService
メソッドをオーバーライドします。 それらの ServiceReference
パラメーターは、アクティブなサービスオブジェクトを参照します。
以下は、 OSGi AllianceのOSGi Core Release 7仕様からの ServiceTracker
実装の例です。
new ServiceTracker<HttpService, MyServlet>(context, HttpService.class, null) {
public MyServlet addingService(ServiceReference<HttpService> reference) {
HttpService httpService = context.getService(reference);
MyServlet myServlet = new MyServlet(httpService);
return myServlet;
}
public void removedService(
ServiceReference<HttpService> reference, MyServlet myServlet) {
myServlet.close();
context.ungetService(reference);
}
}
HttpService
がOSGiレジストリに追加されると、この ServiceTracker
は、新しく追加されたサービスを使用する新しいラッパークラス MyServlet
作成します。 サービスがレジストリから削除されると、 removedService
メソッドが関連リソースをクリーンアップします。
ServiceTracker
メソッドを直接オーバーロードする代わりに、 org.osgi.util.tracker.ServiceTrackerCustomizer
作成します。
class MyServiceTrackerCustomizer
implements ServiceTrackerCustomizer<SomeService, MyWrapper> {
private final BundleContext bundleContext;
MyServiceTrackerCustomizer(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
@Override
public MyWrapper addedService(
ServiceReference<SomeService> serviceReference) {
// Determine if the service is one that's interesting to you.
// The return type of this method is the `tracked` type. Its type
// is what is returned from `getService*` methods; useful for wrapping
// the service with your own type (e.g., MyWrapper).
if (isInteresting(serviceReference)) {
MyWrapper myWrapper = new MyWrapper(
serviceReference, bundleContext.getService());
// trigger the logic that requires the available service(s)
triggerServiceAddedLogic(myWrapper);
return myWrapper;
}
// If the return is null, the tracker is effectively ignoring any further
// events for the service reference
return null;
}
@Override
public void modifiedService(
ServiceReference<SomeService> serviceReference, MyWrapper myWrapper) {
// handle the modified service
}
@Override
public void removedService(
ServiceReference<SomeService> serviceReference, MyWrapper myWrapper) {
// finally, trigger logic when the service is going away
triggerServiceRemovedLogic(myWrapper);
}
}
ServiceTracker
コンストラクターの3番目のパラメーターとして渡して、 ServiceTrackerCustomizer
登録します。
ServiceTrackerCustomizer<SomeService, MyWrapper> serviceTrackerCustomizer =
new MyServiceTrackerCustomizer();
ServiceTracker<SomeService, MyWrapper> serviceTracker =
new ServiceTracker<>(
bundleContext, SomeService.class, serviceTrackerCustomizer);
作成する必要がある小さな定型コードがありますが、プラグインが宣言型サービスコンポーネントモデルを利用できない場合でも、サービスレジストリでサービスを検索できるようになりました。