3

私は OSGI を初めて使用します。サービスを登録する方法を理解しようとしていますか? それは常にBundleContextオブジェクトを介してActivatorですか?利用可能な代替方法はありますか?

インターフェイスIServiceがあり、2 つの実装がServiceImpl1ありServiceImpl2、同じバンドルに以下のように登録しているとします。

context.registerService(IService.class.getName(), new ServiceImpl1(), props);
context.registerService(IService.class.getName(), new ServiceImpl2(), props);

しかし、特定のサービスの実装を具体的にどのように要求すればよいのでしょうか?

serviceImplObject = (IService) dictionaryServiceTracker.getService();</pre>

この場合、どの実装が得られるかわかりません。また、必要なサービス実装のタイプを設定するオプションが表示されませんか?

4

3 に答える 3

5

宣言的にサービスを登録して利用するための代替手段があります。宣言型サービス(DS)またはブループリントサービスのいずれかを使用できます。他にもありますが、これらは実際の仕様の一部です。

現在使用しているプログラムによるアプローチについては。登録時にプロパティを使用し、トラッカーを作成するときにフィルターを使用する必要があります。

Map<String, String. prop1 = new HashMap<String, String>();
prop1.put("name", "primary");
context.registerService(IService.class.getName(), new ServiceImpl1(), prop1);

Map<String, String. prop2 = new HashMap<String, String>();
prop1.put("name", "secondary");
context.registerService(IService.class.getName(), new ServiceImpl2(), props);

さて、ルックアップのために。

ServiceTracker primaryTracker = new ServiceTracker(bundleContext, "(&(objectClass=my.service.Service)(name=primary))", null);
ServiceTracker secondaryTracker = new ServiceTracker(bundleContext, "(&(objectClass=my.service.Service)(name=secondary))", null);

(ランキングに関して更新-Neilに感謝) フィルターがないと、ランキングとサービスIDに基づいてサービスを取得できます。動的環境(これらのサービスが停止および再起動している)で実行している場合は、サービスが検索されるたびに異なる実装を取得することができます。

于 2012-12-20T15:30:56.067 に答える
2

サービスを登録する簡単な方法は次のとおりです。宣言型サービスとbndで提供されるアノテーションを使用します。

@Component
public class ServiceImpl implements IService {
    // ...
}

これで、ServiceImplクラスがインスタンス化され、サービスとして公開されます。サービスを利用する場合、次のようになります(最も単純な場合)。

@Component
public class ServiceImpl2 {
    // ...

    @Reference
    public void setFoo(IService foo) {
        // ..
    }
}
于 2012-12-20T20:26:26.547 に答える
1

アクティベーターは絶対に使用しないでください。注釈付きの DS コンポーネント (Neil の回答を参照) は、OSGi でのベスト プラクティスです。また、DS では Service Tracker は不要になりました。OSGi をもう一度やらなければならないとしたら、アクティベーターもサービス トラッカーもなく、DS だけです。

次に、サービスの選択についてです。最悪の OSGi コンポーネントは、賢く、特定の実装を選択したいコンポーネントです。IService に依存している場合は、取得する実装を気にする必要はありません。本当に Impl1 が必要な場合は、Impl1 への依存関係を指定します。これらの決定を行おうとすると、コンポーネントの再利用性が大幅に低下します。この種のコードを削除するだけで、企業での再利用性が大幅に向上した回数は驚くべきものです。

DS の最も優れた点の 1 つは、デプロイ担当者 (ボックスを制御する担当者) が、どのサービスを誰にバインドするかを決定できることです。それらの人々は自分たちの世界について非常に多くの知識を持っているため、開発者としてのあなたは彼らに任せます。

DS でのサービスのバインドを制御する OSGi メカニズムは、Configuration Admin を介して行われます。コンポーネントが登録したサービスに対して、参照(依存関係)やランキング(またはプロパティ)の対象フィルターを設定できます。したがって、DS では、これは構成可能な決定になります。

繰り返しになりますが、選択が行われる情報が実際にドメインの一部でない限り、この選択コードをすべて削除することを強くお勧めします。その場合は、すべてのサービスを取得し、バインド メソッドでそれらをフィルタリングするだけです。

于 2012-12-21T08:16:29.930 に答える