2017-07-14 2 views
0

私はサービスを公開するOSGiアプリケーション(felix scrアノテーション付き)に取り組んでいます。サービスは、String値を渡すことによって外部APIを登録します。OSGi felix scrアノテーションでサービスするランタイムパラメータを渡す

listener.addSchemaChangeListener(new ChangeListener() 
      { 
       @Override 
       public void schemaChange(ChangeEvent changeEvent) 
       { 
        String schemaName = changeEvent.getSchemaName(); 

        if (null != myBuilder && schemaList.contains(schemaName)) 
        { 
         initVariables(); 
        } 
       } 
      }, "SCHEMA1"); 

サービスは、私は、様々なバンドルで、このサービスを再利用する予定ですmulitple値「SCHEMA1」、「SCHEMA1」、「SCHEMA3」... のリスナーを登録するには上記のコード部分を使用しています。しかし、私はすべての代わりにSCHEMA1の変更だけを聞きたいです。

@Reference(名= "ServiceListener"」、ポリシー= ReferencePolicy.DYNAMIC、基数= ReferenceCardinality.MANDATORY_UNARY、バインド= "バインド"、アンバインド= "アンバインド"、referenceInterface = ServiceListener.class) プライベートAtomicReference myServiceListener =新しいAtomicReference <>();

私は@Referenceで別のサービスでそれを使用しようとすると、その後 ように、特定のスキーマの変更をリッスンするためにサービスを提供するために値を渡すために何の規定はありませんサービスはr私のバンドルでは、スキーマのリストを渡すだけですべての代わりに聞くことができます。 activateメソッドは、いったんサービスが使用クラス(コンポーネント)で正しくバインドされると呼び出されるためです。 この機能を実現するためのOSGiの規定はありますか?

答えて

0

1つの方法は、スキーマごとに1つのサービスを作成することです。これを行うには、スキーマ名を構成値として指定し、いくつかのconfigを使用します。そのような各サービスは、この設定パラメータをサービスプロパティとして持つことになります。したがって、クライアントはスキーマプロパティをフィルタリングできます。

これらの設定を使用しない場合は、ファクトリを提供する1つのサービスを作成できます。その後、各クライアントはファクトリをバインドし、ファクトリのcreateメソッドでスキーマ名を指定してインスタンスを作成します。

3

あなたのアプリケーションが実際にどのように動作しているかについての説明はほとんど含まれていないため、この質問に答えるのは難しいです。

あなたが共有しているコードからは、かなり悪いパターンに従っているように見えます。リスナーパターンは、多くの同期問題とメモリリークの原因です。OSGiを使用しているときは、ホワイトボードパターンを優先する必要があります。

ホワイトボードパターンはかなりシンプルです。各リスナーにサービスをルックアップして登録させるのではなく、モデルを逆転させます。イベントソース(この場合はスキーマ変更)は、OSGiサービスレジストリに登録されているリスナーサービスを検索します。そのようにすれば、リスナーは簡単に記述してフィルタリングすることができ、コードにリスナロジックを追加/削除するのが面倒でエラーが発生しにくくなります。

より良いモデルでは、サービスプロパティを使用して特定のスキーマを選択し、このようなもの(標準のOSGiアノテーションを使用)を表示します。SCHEMA1のイベントの

リスナ1(SCHEMA1の変更をリスン)

@Component(
    property="schemaName=SCHEMA1") 
public class MyListener implements ChangeListener { 
    // Your implementation in here 
} 

リスナー2(SCHEMA1、SCHEMA2、及びSCHEMA3の変更をリスン)

@Component(
    property={"schemaName=SCHEMA1", 
       "schemaName=SCHEMA2", 
       "schemaName=SCHEMA3"}) 
public class MyListener implements ChangeListener { 
    // Your implementation in here 
} 

例出典:

@Component 
public class MyListener implements ChangeListener { 

    @Reference(policy=DYNAMIC, target="(schemaName=SCHEMA1)") 
    private final List<ChangeListener> listeners = new CopyOnWriteArrayList<>(); 

    private void onSchemaChange(ChangeEvent event) { 
     listeners.forEach(l -> l.schemaChange(event); 
    } 

    // Rest of your implementation in here 
} 
関連する問題