8

現在、実行中の Service Factory を含む単純なバンドルを取得しようとしています。

これは私のファクトリークラスです:

public class SvcFactory implements ServiceFactory<ServiceB> {

    @Override
    public ServiceB getService(Bundle bundle,
            ServiceRegistration<ServiceB> registration) {

        return new ServiceBImpl();
    }

    @Override
    public void ungetService(Bundle bundle, ServiceRegistration<ServiceB> registration,
            ServiceB service) {

    }

}

これは、ファクトリによって作成される必要がある私のサービスです。

public class ServiceBImpl implements ServiceB {

    private ServiceA svcA;

    public void setA(ServiceA a) {
        svcA = a;
    }

}

そして最後に OSGI-INF/component.xml

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="bundleb.internal.SvcFactory">

   <implementation class="bundleb.internal.SvcFactory"/>

  <reference bind="setA" cardinality="1..1" interface="bundlea.ServiceA" name="ServiceA" policy="static"/>

   <service servicefactory="true">
      <provide interface="bundleb.ServiceB"/>
   </service>
</scr:component>

equinox 内でテスト バンドル (A、B、および C) を実行すると、次のエラーが発生します。

org.osgi.framework.ServiceException: org.eclipse.equinox.internal.ds.FactoryReg.getService() returned a service object that is not an instance of the service class bundleb.ServiceB

インターネット上のコンポーネント定義で宣言された ServiceFeactories の使用に関する情報はあまり見つかりません。「OSGi and Equinox」という本でさえ、OSGi の使用についてはあまり教えてくれませんでした。誰かが私が間違っていることを説明してもらえますか?

4

3 に答える 3

1

実際にはかなり単純です... DS はバンドルごとにインスタンスを作成するため、DS では Service Factory を実装しなくても、DS がすべての面倒な作業を行います。例えば:

@Service(serviceFactory=true) 
public class MyServiceFactory implements XyzService {

   ...
   @Activate
   void activate(ComponentContext ctx) {
      System.out.println("Using bundle: " + ctx.getUsingBundle());
   }
}

別のバンドルがこの XyzService を取得するたびに、DS は新しいインスタンスを作成します。ComponentContext (オプションで activate メソッドで渡される) を使用して、使用しているバンドルを取得できます。

于 2011-08-19T04:10:56.660 に答える
0

ServiceFactoryコードでさまざまなバンドル用にカスタマイズされたサービス オブジェクトを提供できます。ServiceFactoryでは、サービスのクライアントは、新しいインスタンスがいつ作成されるかを制御しないことに注意してくださいServiceB。通常どおり、サービスのインターフェース ( ) によってサービスを検索します。したがって、彼らにとっては、サービスが登録されているかどうかに違いはありServiceFactoryません。

宣言型サービスでは、自分で実装しないでServiceFactoryください。servicefactory="true"要素に属性を追加するだけ<service>で (すでに行っています)、コンポーネント クラスのさまざまなインスタンスが、さまざまな要求バンドルに対して自動的に作成 (アクティブ化) されます。ServiceBImplコンポーネントの実装クラスとして指定する必要があります。

于 2011-08-12T02:19:34.730 に答える