Je commence tout juste à utiliser OSGI et les services déclaratifs (DS) en utilisant Equinox et Eclipse PDE.OSGI Declarative Services (DS): Quelle est la meilleure façon d'utiliser les instances de composants de service?
J'ai 2 ensembles A et B. Le groupe A expose un composant qui est consommé par le groupe B. Les deux groupes exposent également ce service au registre du service OSGI. Tout fonctionne très bien jusqu'à présent et Equinox relie les composants ensemble, ce qui signifie que le bundle A et le bundle B sont instanciés par Equinox (en appelant le constructeur par défaut), puis le câblage se fait en utilisant les méthodes bind/unbind.
Maintenant, alors qu'Equinox crée les instances de ces composants/services, j'aimerais savoir quelle est la meilleure façon d'obtenir cette instance?
donc supposer qu'il ya troisième classe classe qui est pas instancié par OSGI:
Class WantsToUseComponentB{ public void doSomethingWithComponentB(){ // how do I get componentB??? Something like this maybe? ComponentB component = (ComponentB)someComponentRegistry.getComponent(ComponentB.class.getName()); }
Je vois les options suivantes en ce moment:
1. Utilisez un ServiceTracker dans la Activateur pour obtenir le service de ComponentBundleA.class.getName() (J'ai déjà essayé cela et ça marche, mais ça me semble beaucoup trop lourd) et le rendre disponible via une usine statique méthodes
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. Créer une sorte de registre où chaque registre composants dès que la méthode activate() est appelée.
public ComponentB{ public void bind(ComponentA componentA){ someRegistry.registerComponent(this); }
ou
public ComponentB{ public void activate(ComponentContext context){ someRegistry.registerComponent(this); } }
}
3. Utiliser un registre existant à l'intérieur OSGi/équinoxe qui a ces cas? Je veux dire que OSGI est déjà en train de créer des instances et les relie ensemble, de sorte qu'il a déjà les objets quelque part. Mais où? Comment puis-je les obtenir?
Conclusion D'où vient la classe WantsToUseComponentB (ce qui est un composant et NON instancié par OSGI) obtenir une instance de ComponentB de? Y a-t-il des modèles ou des pratiques exemplaires? Comme je l'ai dit, j'ai réussi à utiliser un ServiceTracker dans l'Activator, mais je pensais que ce serait possible sans cela. Ce que je cherche est en fait quelque chose comme le BeanContainer de Springframework, où je peux juste dire quelque chose comme Container.getBean (ComponentA.BEAN_NAME). Mais je ne veux pas utiliser Spring DS.
J'espère que c'était assez clair. Sinon, je peux aussi poster du code source pour expliquer plus en détail.
Merci Christoph
MIS A JOUR: Réponse au commentaire de Neil:
Merci de clarifier cette question contre la version originale, mais je pense que vous avez encore besoin d'expliquer pourquoi la la troisième classe ne peut pas être créée via quelque chose comme DS.
Hmm ne sait pas. Peut-être y a-t-il un moyen mais je devrais refactoriser tout mon framework pour qu'il soit basé sur DS, de sorte qu'il n'y ait plus de "nouvelles instructions MyThirdClass (arg1, arg2)". Je ne sais pas vraiment comment faire cela, mais j'ai lu quelque chose à propos de ComponentFactories dans DS. Ainsi, au lieu de faire un
MyThirdClass object = new MyThirdClass(arg1, arg2);
Je pourrais faire une
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? }
Au moment de l'écriture, je ne sais pas exactement comment utiliser les ComponentFactories mais ce qui est censé être une sorte de code de pseudo :)
Merci Christoph
Merci pour votre réponse Neil. Ok, supposons que la 3ème classe soit une classe dans ma propre structure héritée et qu'un objet ne puisse pas être créé par DS. Je voudrais savoir si le chemin du ServiceTracker statique et la méthode d'usine statique à l'intérieur de l'Activator sont un bon moyen? Pour moi, il semble un peu hacky, mais je ne sais pas pourquoi. Je ne veux pas utiliser les ServiceTrackers statiques partout mais maintenant c'est comme ça que je le fais. Y a-t-il une meilleure approche? Je suppose qu'il y a :) Merci Christoph – Christoph
Salut Neil, J'ai mis à jour les questions à nouveau (voir la mise à jour en bas) pour répondre à votre question initiale. – Christoph