Ich beginne gerade mit OSGI und deklarativen Diensten (DS) mit Equinox und Eclipse PDE.OSGI Deklarative Services (DS): Was ist eine gute Möglichkeit, Servicekomponenteninstanzen zu verwenden?
Ich habe 2 Bundles, A und B. Bundle A stellt eine Komponente, die von Bundle B. verbraucht wird Beiden Bundles diesen Service auch auf den wieder Registry OSGi Service aussetzen.
Alles funktioniert gut und Equinox verbindet die Komponenten zusammen, was bedeutet, dass Bundle A und Bundle B durch Equinox (durch Aufruf des Standardkonstruktors) installiert werden und dann die Verbindung mit den Bind/Unbind-Methoden erfolgt.
Nun, da Equinox die Instanzen dieser Komponenten/Dienste erstellt, würde ich gerne wissen, was der beste Weg ist, diese Instanz zu bekommen?
es also davon ausgehen, dritte Klasse Klasse ist, die nicht von OSGi instanziiert wird:
Class WantsToUseComponentB{ public void doSomethingWithComponentB(){ // how do I get componentB??? Something like this maybe? ComponentB component = (ComponentB)someComponentRegistry.getComponent(ComponentB.class.getName()); }
ich jetzt folgende Optionen:
1. Verwenden Sie einen Servicetracker in der Activator, um den Service von ComponentBundleA.class.getName() zu bekommen (Ich habe das bereits versucht und es funktioniert, aber es scheint zu viel Overhead für mich) und es über eine statische Fabrik verfügbar machen
public class Activator{ private static ServiceTracker componentBServiceTracker; public void start(BundleContext context){ componentBServiceTracker = new ServiceTracker(context, ComponentB.class.getName(),null); } public static ComponentB getComponentB(){ return (ComponentB)componentBServiceTracker.getService(); }; }
2. Erstellen Sie eine Art von Registry wobei jede Komponente Register, sobald die activate() -Methode aufgerufen wird.
public ComponentB{ public void bind(ComponentA componentA){ someRegistry.registerComponent(this); }
oder
public ComponentB{ public void activate(ComponentContext context){ someRegistry.registerComponent(this); } }
}
3. Verwenden Sie eine vorhandene Registrierung innerhalb osgi/Tagundnachtgleiche, die diese Instanzen hat? Ich meine, OSGI erstellt bereits Instanzen und verbindet sie miteinander, so dass die Objekte bereits irgendwo vorhanden sind. Aber wo? Wie kann ich sie bekommen?
Fazit Woher kommt die Klasse WantsToUseComponentB (die nicht Bestandteil und nicht die von OSGi instanziiert) erhalten eine Instanz von ComponentB aus? Gibt es Muster oder Best Practices? Wie gesagt, ich habe es geschafft, einen ServiceTracker im Activator zu verwenden, aber ich dachte, das wäre ohne ihn möglich.
Was ich suche, ist eigentlich so etwas wie der BeanContainer von Springframework, wo ich einfach etwas wie Container.getBean (ComponentA.BEAN_NAME) sagen kann. Aber ich möchte Spring DS nicht verwenden.
Ich hoffe, das war klar genug. Ansonsten kann ich auch etwas Quellcode posten, um das genauer zu erklären.
Dank Christoph
AKTUALISIERT: Antwort Neil Kommentar:
Vielen Dank für diese Frage gegen die ursprüngliche Version zu klären, aber ich denke immer noch, warum die angeben müssen Die dritte Klasse kann nicht über etwas wie DS erstellt werden.
Hmm weiß es nicht. Vielleicht gibt es einen Weg, aber ich müsste mein gesamtes Framework so umgestalten, dass es auf DS basiert, sodass es keine "neuen MyThirdClass (arg1, arg2)" - Anweisungen mehr gibt. Ich weiß nicht wirklich, wie ich das machen soll, aber ich habe etwas über ComponentFactories in DS gelesen. Anstatt also einen tun
MyThirdClass object = new MyThirdClass(arg1, arg2);
könnte ich tun, um ein
ComponentFactory myThirdClassFactory = myThirdClassServiceTracker.getService(); // returns a if (myThirdClassFactory != null){ MyThirdClass object = objectFactory.newInstance(); object.setArg1("arg1"); object.setArg2("arg2"); } else{ // here I can assume that some service of ComponentA or B went away so MyThirdClass Componenent cannot be created as there are missing dependencies? }
Zum Zeitpunkt des Schreibens ich nicht genau wissen, wie die ComponentFactories zu verwenden, aber dies soll eine Art Pseudo-Code sein :)
Dank Christoph
Danke für deine Antwort Neil. Ok nehme an, die 3. Klasse ist eine Klasse innerhalb meines eigenen Legacy-Frameworks und es gibt ein Objekt, das nicht von DS erstellt werden kann. Ich würde gerne wissen, ob der Weg des statischen ServiceTracker und die statische Fabrikmethode im Activator ein guter Weg ist? Mir scheint es ein bisschen hacky, aber weiß nicht warum. Ich möchte keine statischen ServiceTrackers überall verwenden, aber genau jetzt mache ich es so. Gibt es einen besseren Ansatz? Ich denke, es gibt :) Dank Christoph – Christoph
Hallo Neil, Ich aktualisierte die Fragen erneut (siehe UPDATE am unteren Rand), um Ihre erste Frage zu beantworten. – Christoph