EquinoxとEclipsePDEを使用してOSGIと宣言型サービス(DS)を使い始めたところです。
AとBの2つのバンドルがあります。バンドルAは、バンドルBによって消費されるコンポーネントを公開します。どちらのバンドルも、このサービスをOSGIサービスレジストリに再度公開します。
これまでのところすべてが正常に機能しており、Equinoxはコンポーネントを相互にワイヤリングしています。つまり、バンドルAとバンドルBは(デフォルトのコンストラクタを呼び出すことによって)Equinoxによってインスタンス化され、バインド/アンバインドメソッドを使用してワイヤリングが行われます。
さて、Equinoxがそれらのコンポーネント/サービスのインスタンスを作成しているので、このインスタンスを取得するための最良の方法を知りたいですか?
したがって、OSGIによってインスタンス化されないサードクラスのクラスがあると仮定します。
クラスWantsToUseComponentB{ public void doSomethingWithComponentB(){ // componentBを取得するにはどうすればよいですか?多分このような何か? ComponentBコンポーネント=(ComponentB)someComponentRegistry.getComponent(ComponentB.class.getName()); }
現在、次のオプションが表示されています。
1. ActivatorでServiceTrackerを使用してComponentBundleA.class.getName()のサービスを取得し(すでに試しましたが、機能しますが、かなりのオーバーヘッドがあるようです)、静的ファクトリメソッドを介して利用できるようにします。
パブリッククラスアクティベーター{ プライベート静的ServiceTrackercomponentBServiceTracker; public void start(BundleContext context){ componentBServiceTracker = new ServiceTracker(context、ComponentB.class.getName()、null); } public static ComponentB getComponentB(){ return(ComponentB)componentBServiceTracker.getService(); }; }
2. activate()メソッドが呼び出されるとすぐに各コンポーネントが登録される、ある種のレジストリを作成します。
public ComponentB { public void bind(ComponentA componentA){ someRegistry.registerComponent(this); }
また
public ComponentB { public void activate(ComponentContext context){ someRegistry.registerComponent(this); } }
}
3.それらのインスタンスを持つosgi/equinox内の既存のレジストリを使用しますか?つまり、OSGIはすでにインスタンスを作成し、それらを相互に接続しているので、オブジェクトはすでにどこかにあります。しかしここで?どうすれば入手できますか?
結論 クラスWantsToUseComponentB(これはコンポーネントではなく、OSGIによってインスタンス化されません)はどこからComponentBのインスタンスを取得しますか?パターンやベストプラクティスはありますか?先ほど言ったように、ActivatorでServiceTrackerを使用することができましたが、それがなくても可能だと思いました。
私が探しているのは、実際にはSpringframeworkのBeanContainerのようなもので、Container.getBean(ComponentA.BEAN_NAME)のようなものを言うことができます。しかし、私はSpringDSを使いたくありません。
それが十分に明確だったことを願っています。それ以外の場合は、ソースコードを投稿して詳細を説明することもできます。
ありがとうクリストフ
更新: ニールのコメントへの回答:
元のバージョンに対してこの質問を明確にしていただきありがとうございますが、DSなどを使用して3番目のクラスを作成できない理由を説明する必要があると思います。
うーん、わかりません。方法はあるかもしれませんが、フレームワーク全体をリファクタリングしてDSに基づくようにし、「new MyThirdClass(arg1、arg2)」ステートメントがなくなるようにする必要があります。その方法はよくわかりませんが、DSのComponentFactoriesについて何か読んでいます。だから、する代わりに
MyThirdClassオブジェクト=newMyThirdClass(arg1、arg2);
私はするかもしれません
ComponentFactory myThirdClassFactory = myThirdClassServiceTracker.getService(); //を返します if(myThirdClassFactory!= null){ MyThirdClassオブジェクト=objectFactory.newInstance(); object.setArg1( "arg1"); object.setArg2( "arg2"); } そうしないと{ //ここでは、ComponentAまたはBの一部のサービスが停止したため、依存関係が欠落しているためMyThirdClassコンポーネントを作成できないと想定できますか? }
これを書いている時点では、ComponentFactoriesの使用方法は正確にはわかりませんが、これはある種の擬似コードであると思われます:)
ありがとうクリストフ