Abhängigkeitsinjektion in OSGI-Umgebungen
Zuerst etwas hintergrund:
Arbeite ich an einigen webapp-Prototyp-code, basierend auf Apache Sling die OSGI-basiert und läuft auf Apache Felix. Ich bin noch relativ neu in OSGI-obwohl ich denke, dass ich verstanden haben die meisten Konzepte, die von jetzt. Aber was mich verwirrt ist, dass ich nicht in der Lage zu finden ein "volle" dependency injection (DI) Frameworks. Ich habe erfolgreich eingesetzt rudimentäre DI mit Deklarativen Services (DS). Aber mein Verständnis ist, dass DS verwendet werden, um Referenz -- wie mache ich das? -- OSGI-registrierte Dienste und Komponenten zusammen. Und für die, die es funktioniert gut, aber ich persönlich nutze DI-frameworks wie Guice Draht gesamten Objekt-Graphen zusammen und legen Sie Objekte auf die richtigen Bereiche (denken @RequestScoped
oder @SessionScoped
zum Beispiel). Aber keiner von der OSGI-spezifische frameworks habe ich mir angeschaut, scheinen für dieses Konzept.
Habe ich begann zu Lesen über OSGI-Blaupausen und iPOJO aber diese Rahmenbedingungen scheinen sich mehr Gedanken über die Verdrahtung von OSGI-services zusammen als mit der Bereitstellung einer full-DI-Lösung. Ich muss zugeben, ich habe nicht getan, alle Proben noch, so mein Eindruck könnte falsch sein.
Eine Erweiterung zu Guice, ich habe experimentierte mit Peaberry, aber ich fand die Dokumentation sehr schwer zu finden, und während ich mich für den basic-DI arbeiten, eine Menge von guice-servlet-advanced-Funktionalität (automatische Injektion in filtern, servlets, etc) hat überhaupt nicht funktioniert.
So, meine Fragen sind die folgenden:
- Wie deklarative Leistungen vergleichen "traditionelle" DI wie Guice oder Spring? Tun Sie dasselbe problem zu lösen oder sind Sie darauf ausgerichtet, die verschiedenen Probleme?
- Alle OSGI-spezifische Lösungen, die ich bisher gesehen habe, fehlt das Konzept der scopes für DI. Zum Beispiel, Guice + guice-servlet hat die request-scoped Abhängigkeiten, die macht das schreiben von web-Anwendungen wirklich sauber und einfach. Habe ich nur übersehen, dass in den docs oder sind diese Bedenken nicht abgedeckt durch eines dieser frameworks?
- Sind JSR 330 und OSGI-basierten DI-zwei verschiedene Welten? iPOJO zum Beispiel bringt seine eigene Anmerkungen und Felix SCR Anmerkungen zu sein scheinen eine völlig andere Welt.
- Hat jemand Erfahrung mit dem Bau von OSGI-basierten Systemen und DI? Vielleicht auch einige Beispiel-code auf github?
- Hat jemand Verwendung verschiedener Technologien wie Guice und iPOJO zusammen oder ist das nur eine verrückte Idee?
Sorry für die ziemlich lange Frage.
Jedes feedback wird sehr geschätzt.
Updates
Gültigkeitsbereich Injektion: scoped-Injektion ist ein nützlicher Mechanismus, um Objekte aus einer bestimmten Lebenszyklus automatisch injiziert. Denken Sie zum Beispiel, einige Ihrer code stützt sich auf eine Hibernate-session-Objekt, das erstellt wird, als Teil der einen servlet-filter. Durch das markieren einer Abhängigkeit der container wird automatisch neu erstellen Sie das Objekt graph. Vielleicht gibt es nur verschiedene Ansätze?
JSR 330 vs DS: von allen hervorragenden Antworten, die ich sehen, dass diese sind zwei verschiedene Dinge. Stellt sich noch die Frage, wie man mit Bibliotheken von Drittanbietern und frameworks, die Verwendung JSR 330 Annotationen beim Einsatz in einer OSGI-Kontext? Was ist ein guter Ansatz? Läuft ein JSR 330-container innerhalb des Pakets?
Ich Schätze Ihre Antworten, Sie waren sehr hilfreich!!!
InformationsquelleAutor der Frage ilikeorangutans | 2012-06-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gesamtkonzept
Der einfachste Weg, um dependency injection mit Apache Sling, und die man in der gesamten Codebasis, ist die Verwendung der maven-scr-plugin .
Können Sie kommentieren Sie Ihren java-Klassen und dann, zur build-Zeit berufen sich auf die SCR-plugin, entweder als ein Maven-plugin, oder als Ant-task.
Beispielsweise, registrieren Sie einen servlet können Sie das folgende tun:
Konkrete Antworten
Lösen Sie das gleiche problem - dependency injection. Aber (siehe unten), Sie Bauten auch zu berücksichtigen, dynamische Systeme, in denen Dienste können erscheinen oder verschwinden zu jeder Zeit.
Ich habe nicht gesehen, jeder Ansatz, der in der SCR-Welt hinzufügen, session-scoped oder request-scoped services. Aber SCR ist ein generischer Ansatz, und Bereiche behandelt werden können, auf einer bestimmten Ebene.
Da bist du mit Schlinge ich denke, dass es wenig Bedarf für session-scoped oder request-scoped-Bindungen, da Sling hat builtin-Objekte für jede Anforderung die entsprechend für den aktuellen Benutzer erstellt.
Ein gutes Beispiel dafür ist der JCR-Sitzung. Es wird automatisch aufgebaut mit korrekten Berechtigungen und es ist in der Praxis ein request-scoped DAO. Das gleiche gilt für den Sling resourceResolver.
Wenn Sie feststellen, selbst benötigen, die pro-user-Arbeit der einfachste Ansatz besteht darin, Dienstleistungen, die Sie erhalten einen JCR
Session
oder SchlingeResourceResolver
und verwenden Sie diese zum ausführen der arbeiten müssen Sie. Die Ergebnisse werden automatisch angepasst, für die Berechtigungen des aktuellen Benutzers ohne zusätzlichen Aufwand.Ja, Sie sind anders. Sie sollten im Hinterkopf behalten, dass, obwohl Spring und Guice sind mehr mainstream, OSGi-services sind komplexer und die Unterstützung für weitere Anwendungsfälle. In OSGi-bundles ( und implizit services ) sind frei, kommen und gehen zu jeder Zeit.
Dies bedeutet, dass, wenn Sie eine Komponente, die abhängig von einer Dienstleistung, die wurde gerade nicht verfügbar Komponente ist deaktiviert. Oder wenn Sie erhalten eine Liste von Komponenten ( zum Beispiel Servlet-Implementierungen), und einer von Ihnen deaktiviert ist, werden Sie benachrichtigt. Meines Wissens nach, weder Frühling noch Guice unterstützt diese als Ihre Verdrahtungen sind statisch.
Dass eine große Menge an Flexibilität, die OSGi bietet Ihnen.
Gibt es eine große Anzahl von Proben in der Sling Proben SVN-repository . Sollten Sie feststellen, dass die meisten von dem, was Sie dort brauchen.
Wenn Sie Rahmenbedingungen, die konfiguriert sind, mit JSR 330 Annotationen, macht es Sinn, so konfigurieren, dass Sie zur Laufzeit mithilfe von Guice oder Spring oder was auch immer für Sie arbeitet. Jedoch, wie Neil Bartlett hat darauf hingewiesen, das wird nicht funktionieren, cross-bundles.
InformationsquelleAutor der Antwort Robert Munteanu
Ich möchte nur hinzufügen, ein wenig mehr Informationen zu Robert ' s ausgezeichnete Antwort, insbesondere im Hinblick auf JSR330 und DS.
Deklarative Services, Blueprint, iPOJO und die anderen OSGi - "Komponenten-Modelle" sind in Erster Linie soll für die Injektion von OSGi-services. Diese sind etwas schwieriger zu handhaben als normale Abhängigkeiten, da können Sie kommen und gehen zu jeder Zeit, auch in Reaktion auf externe Ereignisse (z.B. Netzwerk getrennt ist) oder die user-Aktionen (z.B. dem bundle entfernt). Daher sind alle diese Modelle bieten einen zusätzlichen lifecycle Schicht über reines dependency injection-frameworks.
Dies ist der Hauptgrund, warum die DS-Annotationen unterscheiden sich von den JSR330 sind... die JSR330 nicht genügend Semantik, befassen sich mit Lebensdauer. Zum Beispiel, sagen Sie nichts über:
Leider, denn die Modelle sind in Erster Linie auf Dienstleistungen, - das heißt, die verbindungen zwischen bundles -- Sie sind vergleichsweise spartanisch hinsichtlich der Verdrahtung Abhängigkeiten innen das bundle (obwohl Blueprint bietet einige Unterstützung für diese).
Sollte es kein problem sein mit einer vorhandenen DI-framework für die Verkabelung Abhängigkeiten im bundle. Zum Beispiel hatte ich einen Kunden, der Guice verwendet, verdrahten Sie den internen Stücke einiger Deklarative Services-Komponenten. Allerdings Neige ich dazu, die Frage Wert, dies zu tun, denn wenn Sie brauchen, DI in Ihrem bundle-es deutet darauf hin, dass Ihre bundle kann zu groß sein und unzusammenhängend.
Beachten Sie, dass es ist sehr wichtig, NICHT zu verwenden einen traditionellen DI-framework zu verdrahten Komponenten zwischen bundles. Wenn das DI-framework benötigt, um Zugriff auf eine Klasse aus einem anderen bundle, dass dann andere bundle Belichten muss seine Umsetzung details, bricht die Kapselung, die wir suchen in OSGi.
InformationsquelleAutor der Antwort Neil Bartlett
Habe ich einige Erfahrung im Aufbau von Anwendungen mit Aries Blueprint. Es hat einige sehr nette features, über OSGi-services und die config-admin-support.
Wenn Sie suchen für einige tolle Beispiele haben Sie einen Blick auf den code von Apache Karaf, die verwendet Blaupause für alle seine Verdrahtung.
Sehen http://svn.apache.org/repos/asf/karaf/
Ich habe auch einige tutortials für den Entwurf und die Apache Karaf auf meiner website:
http://www.liquid-reality.de/display/liquid/Karaf+Tutorials
In Ihrer Umgebung mit der embedded-felix wird es ein bisschen anders, da Sie nicht über die management-Funktionen von Karaf, aber Sie müssen einfach zu installieren, die die gleichen bundles und es sollte gut funktionieren.
InformationsquelleAutor der Antwort Christian Schneider
Ich bin mit osgi und DI für aktuelle für mein Projekt habe ich ausgewählt gemini blueprint, denn es ist die zweite version von SPRING DYNAMIC MODULE, Basierend auf diesen Informationen, die ich schlage vor, Sie Lesen Spring Dynamic Modules in Action. Dieses Buch wird Ihnen helfen, zu verstehen, einige Teile und Punkte, wie bauen, Architektur und warum ist es gut 🙂
InformationsquelleAutor der Antwort Sergii Zagriichuk
Kann ich nur empfehlen, Bnd und wenn Sie mit Eclipse IDE sepcially Bndtools als gut. Mit dass Sie vermeiden können, beschreibt DS im XML-und die Verwendung von Annotationen statt. Es ist eine Besondere
Reference
Anmerkung für DI. Dieser hat auch einen filter, wo Sie den Verweis auf nur eine spezielle Teilmenge von Dienstleistungen.InformationsquelleAutor der Antwort christian.vogel
Läuft in eine ähnliche Architektur problem hier - wie Robert oben schon erwähnt in seiner Antwort:
Extrapolation aus diesem (und was ich bin derzeit coding), ein Ansatz wäre hinzuzufügen
@param resourceResolver
zu jedem@Service
Methoden, so dass Sie weitergeben können und entsprechend request-scoped-Objekt verwendet werden, die Ausführung Kette.Speziell haben wir eine
XXXXService
/XXXXDao
Schicht, genannt vonXXXXServlet
/XXXXViewHelper
/JSP-äquivalente. Damit die Verwaltung all dieser Komponenten über die OSGI -@Service
Anmerkungen, können wir leicht den Draht, bis der gesamte Stapel.Der Nachteil hier ist, dass Sie brauchen, um Wurf Ihre interface-design mit
ResourceResolver
oderSessions
params.Ursprünglich haben wir versucht zu injizieren
ResourceResolverFactory
in der DAO-Schicht, so dass wir jederzeit Zugriff auf die session wird über die Fabrik. Wir sind jedoch der Interaktion mit der session an mehreren Punkten in der Hierarchie, und mehrere Male pro Anfrage. Dies führte in der Sitzung-geschlossen Ausnahmen.Gibt es eine Möglichkeit an die pro-Anfrage
ResourceResolver
zuverlässig ohne pass in jede service-Methode?Request-scoped-Injektion auf den Service-Layer, könnten Sie stattdessen einfach die ResourceResolver, als constructor-arg & verwenden Sie eine Instanz-variable statt. Natürlich ist der Nachteil hier ist, würden Sie zu denken haben, request-scope vs. Prototyp-Umfang service-code und trennen sich entsprechend.
Dies scheint, wie es wäre ein häufiges problem, wo Sie wollen, zu trennen Anliegen in service - /dao-code, verlassen des JCR-Interaktionen in der DAO, Analog zu Überwintern wie kann man schnell an die pro-Anfrage
Session
durchführen repo operataions?InformationsquelleAutor der Antwort radmike