2

構成ごとに作成する必要があるサービスがあり、それぞれが外部リソースに依存しているため、独自のライフサイクルを管理する必要があります (つまり、サービスを登録 (登録解除) します)。したがって、これらを DS として実装し、SCR が複数のインスタンスを生成できるようにすることはできません。

このタスクを完全に達成するために、ManagedServiceFactory を登録するバンドルを実装できます (私の以前の投稿を参照してください)。しかし結果として、ファクトリが他のいくつかのサービスに依存している場合は、それらのサービスの追跡を開始し、すべてを実行するために多くのグルー コードを記述する必要があります。ManagedServiceFactory代わりに、SCRがサービス レジストリに登録する (シングルトンの) 宣言型サービスとしてファクトリを実装したいと考えています。

これが私の試みです:

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory;
import org.osgi.service.component.ComponentContext;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class Factory implements ManagedServiceFactory {

private BundleContext bundleCtxt;
private Map<String, ServiceRegistration> services;

public void activate(ComponentContext context) throws Exception {
    System.out.println("actiavting...");
    this.bundleCtxt = context.getBundleContext();
    services = new HashMap<String, ServiceRegistration>();
}

public void deactivate(ComponentContext context) {
    for(ServiceRegistration reg : services.values()) {
        System.out.println("deregister " + reg);
        reg.unregister();
    }
    services.clear();
}

@Override
public String getName() {
    System.out.println("returning factory name");
    return "my.project.servicefactory";
}


@Override
public void updated(String pid, Dictionary properties)
        throws ConfigurationException {
    System.out.println("retrieved update for pid " + pid);
    ServiceRegistration reg = services.get(pid);
    if (reg == null) {
        services.put(pid, bundleCtxt.registerService(ServiceInterface.class,
                new Service(), properties));
    } else {
        // i should to some update here
    }
}

@Override
public void deleted(String pid) {
    ServiceRegistration reg = services.get(pid);
    if (reg != null) {
        reg.unregister();
        services.remove(pid);
    }
}
}

およびサービスの説明:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" configuration-policy="ignore" name="my.project.servicefactory">
   <implementation class="my.project.factory.Factory"/>
   <service>
      <provide interface="org.osgi.service.cm.ManagedServiceFactory"/>
   </service>
   <property name="service.pid" type="String" value="my.project.servicefactory"/>
</scr:component>

サービス説明の「factory」プロパティが間違ったパスであることは既にわかりました。この方法では、コンポーネントがManagedServiceFactoryサービス レジストリのように登録されず、代わりにComponentFactory.

一種のハックとして、コンポーネント プロパティを追加しました。

<property name="service.pid" type="String" value="my.project.servicefactory"/>

と追加しましconfiguration-policy="ignore"た。これは機能します。指定された構成my.project.servicefactory-foobar.cfgは私のサービスに渡され、サービス レジストリに登録されます。すべて問題ありません。

しかし、私が気に入らないことが2つあります。

  1. プロパティを手動で設定することservice.pidは、私には汚いハックのように感じます
  2. 設定configuration-policy="ignore"すると、それ自体を構成できなくなりますManagedServiceFactory。このプロパティをエスケープするか、require に設定すると、という名前の構成に対して 1 つ取得ManagedServiceFactoryし、patternでmy.project.servicefactory.cfg名前を付けた構成ごとに 2 つのサービスを取得します。 . (SCRが工場出荷時の設定のプロパティを上書きするため、少なくともこれは指数関数的に増加していません)my.project.servicefactory-foobar.cfgManagedServiceFactoryServiceInterfaceManagedServiceFactoryservice.pid

では、これを適切に設定するにはどうすればよいでしょうか。

PS: ファイル名の構成への私の参照について疑問に思っている人のために: 私は構成に Felix Fileinstall を使用するためfoo.cfg、 PID の ConfigAdmin に配置され、foofactory -pidfoo-bar.cfg配置されます。foo

4

2 に答える 2

3

Just use your DS instance headless, the properties, and register the service yourself:

@Component(immedate=true, provide={}, serviceFactory=true, configurationPolicy=require)
public class Mine {
    BundleContext context;
    volatile ServiceRegistration r;

    @Activate
    void activate(BundleContext context, Map<String,Object> map) {
         this.context = context;
         track(map);
    }

    @Deactivate
    void deactivate() {
        if ( r != null)
              r.unregisterService();
    }

    void track(Map<String,Object> map) {
       ... // do your remote stuff
       r = context.registerService(...);
       ...
    }
}
于 2012-08-13T07:51:28.710 に答える
2

これに対する DS のサポートが機能しないのはなぜですか? 112.6 を参照:

Factory Configuration – If a factory PID exists, with zero or more Configurations, that is equal to the configuration PID, then for each Configuration, a component configuration must be created that will obtain additional component properties from Configuration Admin.

これは、コンポーネントの構成 pid が CM のファクトリ pid と同じ場合、DS はファクトリ pid の下に構成ごとにコンポーネントのインスタンスを作成することを示しています。

于 2012-08-08T16:45:34.900 に答える