さまざまなコンテキストで機能を同じにする必要があるアプリケーションを設計しています。下の写真を参照してみましょう。
+ ---- + + ---- + + ---- + | B1 + ---> ----- + B2 +-> ---- + B3 | | ctx1 | |ctx1|を使用します |ctx1|を使用します +----+サービス+----+サービス+----+ + ------- + + ---- + + ---- + + ---- + |コンテキスト| | B1 + ---> ----- + B2 +-> ---- + B3 | |マネージャー| | ctx2 | |ctx2|を使用します |ctx2|を使用します | | +----+サービス+----+サービス+----+ | | ::: + ------- + ::: + ---- + + ---- + + ---- + | B1 + ---> ----- + B2 +-> ---- + B3 | | ctxN | |ctxN|を使用します |ctxN|を使用します +----+サービス+----+サービス+----+
4つのバンドルがあります:
- コンテキストマネージャー
- B1
- B2
- B3
Context Managerは、新しいコンテキストがいつ利用可能になるかを認識し、 B1、B2、およびB3の新しいバージョンをインスタンス化することを担当するバンドルです。B2とB3によって提供されるサービスは、コンテキスト間でまったく同じです。サービスにプロパティを追加して、実行中のコンテキストを区別したいだけです(たとえば、ctx1とctxN)。これが私が達成したいことの理論です。宣言型サービスを介して簡単に実装できると思いました。実際、コンポーネントヘッダーでcomponent.factoryプロパティを指定することで、B1 * B2 *とB3をComponentFactoryにしました。セットB1B2が提供するサービスを参照するには、 B3が提供するサービスを参照するようにB2を設定します。これらは私が直面した課題です:
- Context Managerは、 B3によってのみ提供されるComponentFactoryサービスについて初めて学習します。これは、 B1とB2がまだ満たされていない限り、ComponentFactoryサービスをサービスレジストリに登録しません。これが当てはまる限り、B1とB2は最初のコンテキストでインスタンス化されません。
- B1とB2が作成されると、他のコンテキストから任意のサービスを取得します。同じコンテキストからのみサービスを選択するようにreference.targetパラメーターを設定することを考えていましたが、これを宣言的に行う方法はないようです。同じコンテキストからサービスを選択する唯一の方法は、カーディナリティ0..nで参照を設定し、現在のコンテキストに基づいて選択する「バインド」メソッドを提供することです。これは、すべてのコンポーネントが同じ選択ロジックを複製する必要があることを意味します代わりに、newInstanceが呼び出されたときにコンテキストマネージャーによって提供されると考えていました。実際、呼び出し中にComponentFactory.newtInstance(props);.target =(context = mycontext)のようなプロパティを提供すると、これを実現できますが、コンポーネントが実際に使用しているすべての参照を知りません。
この時点で、私は実際に宣言型サービスの使用を避け、コンテキストごとのバンドルに提供する基本クラスを拡張させることを考えています。これは、基本的にorg.apache.felicy.dependencymanagerと同様の依存関係の追跡を実装しますが、コンテキストごとのコンポーネントは、コードがどのコンテキストにあるかを知る必要はありません。ただし、このソリューションに戻るのは嫌いです。OSGi仕様にすでに存在する可能性のあるロジックを複製しているだけだと感じているので、私の質問は次のとおりです。
OSGiのコンテキストごとに実行できるバンドルを作成するための最良の方法は何ですか?バンドルは、実行されているコンテキストを明示的に言及することなく、依存関係を宣言的な方法で記述できますか?