3

私の現在のアプリケーションでは、いくつかの場所でこのパターンに遭遇しました。異なるが関連するジョブを実行する 1 つのバンドルに 2 つのサービス インターフェイスがあります。

interface Service1 { ... }

interface Service2 { ... }

両方を実装するシングルトンコンポーネントが必要ですが、それぞれが他方への参照を必要としていることがわかります。

public class Service1Impl implements Service1 { 

    private Service2 service2;
    ...

}

public class Service2Impl implements Service2 { 

    private Service1 service1;
    ...

}

3 つの OSGi コンポーネント モデル (DS、Blueprint、iPOJO) のどれがこれを可能にしますか? 1)Service1ImplService2Implが同じバンドルにある場合。2)それらが異なるバンドルにあるときは?

4

2 に答える 2

6

宣言型サービス仕様、バージョン 1.1:

112.3.5 循環参照

コンポーネント記述のセットが循環依存関係を作成する可能性があります。たとえば、コンポーネント A がコンポーネント B によって提供されるサービスを参照し、コンポーネント B がコンポーネント A によって提供されるサービスを参照する場合、一方のコンポーネントのコンポーネント構成は、他方のコンポーネントの部分的にアクティブ化されたコンポーネント インスタンスにアクセスすることなく満たすことはできません。SCR では、コンポーネント インスタンスが完全にアクティブ化されるまで (つまり、アクティブ化メソッドがある場合はそのメソッドから返されるまで)、別のコンポーネント インスタンスまたはサービスとしてアクセスできないようにする必要があります。

循環参照は、コンポーネント構成を満たそうとするときに SCR によって検出される必要があり、SCR は循環に含まれる参照を満たすことができず、存在する場合はログ サービスにエラー メッセージを記録する必要があります。ただし、サイクル内の参照の 1 つにオプションのカーディナリティがある場合、SCR はサイクルを中断する必要があります。オプションのカーディナリティを使用した参照が満たされ、ゼロのターゲット サービスにバインドされます。したがって、サイクルが壊れ、他の参照が満たされる可能性があります。

ブループリントの仕様では、依存関係サイクルの少なくとも 1 つのメンバーが他のメンバーを引数ではなくプロパティとして受け取る場合に、これを明示的に許可しています (121.2.6 循環依存関係)。

サイクルのメンバーがコンポーネント インスタンスを提供するように要求された場合、Blueprint Container は、サイクルのメンバー内で 1 つの中断メンバーを見つけて、サイクルを中断する必要があります。中断メンバーは、循環を引き起こす依存関係に対してプロパティ インジェクションを使用する必要があります。Blueprint Container は、メンバーを壊すサイクルの適切なメンバーを選択できます。そのようなメンバーが見つからない場合、初期化が失敗するか、getComponentInstance メソッドがコンポーネント定義例外をスローする必要があります。

破壊メンバーは、オブジェクトの提供を求められたときに、部分的に初期化されたコンポーネント インスタンスを返す必要があります。部分的に初期化されたオブジェクトは、考えられるすべての初期化を完了しましたが、initMethod (指定されている場合) でまだ呼び出されておらず、サイクルを引き起こすプロパティが注入されていません。部分的に初期化されたコンポーネント インスタンスのファイナライズは、循環のすべての参照メンバーに破壊メンバーが注入されるまで遅らせる必要があります。ファイナライズとは、残りの未設定のプロパティを注入し、指定されている場合は initMethod を呼び出すことを意味します。

部分的に初期化されたコンポーネント インスタンスの結果、すべてのプロパティが設定される前に使用できるようになるため、アプリケーションはこれを認識する必要があります。

ブループリント コンテナがランタイム フェーズに入る前、および getComponentInstance メソッドの呼び出しがコンポーネント インスタンスを返す前に、部分的に初期化されたすべてのコンポーネント インスタンスをファイナライズする必要があります。getComponentInstance メソッドを再帰的に呼び出すことによって動的なサイクルを引き起こすユーザー コードは、検出されてエラーが発生する必要があります。これらのサイクルは中断できません。

検出されたすべてのサイクルをログに記録する必要があります。

iPOJOの場合

あなたの特定の状況がサポートされています。これ以上の説明がなければ、他の状況について話すことはできません。

(メーリングリストで回答を受け取りました)。

于 2012-05-14T06:12:58.070 に答える
3

厳密に言えば、循環依存のため、あなたが言っていることは不可能です。

Service1はService2がアクティブになったときにのみ機能でき、その逆も同様です。したがって、フレームワークがサービスを開始できる順序はありません。

私が見る限り、サービス参照の1つをオプションにすると、サービスを機能させることができます。これにより、サービスが注入される前にサービスを提供できるため、他のserviceimplがサービスを提供し直すことができます。

これは、3つのフレームワークすべてで実行できます。iPojoにはオプションの参照があり、DSにはサービス要件に対するカーディナリティ設定があります(オプションの参照には1..1ではなく0..1を使用します)。青写真よくわかりませんが、できると思います。

よろしく、フランク

于 2012-05-13T02:48:08.537 に答える