Frage

Ich arbeite mit sehr großen JSF/Facelets-Anwendungen, die Spring für die DI/Bean-Verwaltung verwenden.Meine Anwendungen sind modular aufgebaut und ich suche derzeit nach Ansätzen, die Modularisierung zu standardisieren.

Mein Ziel ist es, eine Webanwendung aus mehreren (ggf. voneinander abhängigen) Modulen zusammenzustellen.Jedes Modul kann Folgendes enthalten:

  • Klassen;
  • Statische Ressourcen (Bilder, CSS, Skripte);
  • Facelet-Vorlagen;
  • Verwaltete Beans – Spring-Anwendungskontexte mit Anforderungs-, Sitzungs- und anwendungsbezogenen Beans (Alternative sind JSF-verwaltete Beans);
  • Servlet-API-Sachen – Servlets, Filter, Listener (dies ist optional).

Was ich (fast um jeden Preis) vermeiden möchte, ist die Notwendigkeit, Modulressourcen (wie Facelets-Vorlagen) in die WAR-Datei zu kopieren oder zu extrahieren oder diese zu erweitern web.xml für Modul-Servlets, Filter usw.Es muss ausreichen, das Modul (JAR, Bundle, Artefakt, ...) zur Webanwendung hinzuzufügen (WEB-INF/lib, bundles, plugins, ...), um die Webanwendung mit diesem Modul zu erweitern.

Derzeit löse ich diese Aufgabe mit einer benutzerdefinierten Modularisierungslösung, die stark auf der Verwendung von Klassenpfadressourcen basiert:

  • Das Servlet für spezielle Ressourcen stellt statische Ressourcen aus Klassenpfadressourcen (JARs) bereit.
  • Der spezielle Facelets-Ressourcen-Resolver ermöglicht das Laden von Facelet-Vorlagen aus Klassenpfadressourcen.
  • Spring lädt Anwendungskontexte über das Muster classpath*:com/acme/foo/module/applicationContext.xml – Dadurch werden Anwendungskontexte geladen, die in Modul-JARs definiert sind.
  • Schließlich delegiert ein Paar delegierender Servlets und Filter die Anforderungsverarbeitung an die Servlets und Filter, die in Spring-Anwendungskontexten von Modulen aus konfiguriert sind.

In den letzten Tagen habe ich viel über OSGi gelesen und überlegt, wie (und ob) ich OSGi als standardisierten Modularisierungsansatz nutzen könnte.Ich habe darüber nachgedacht, wie einzelne Aufgaben mit OSGi gelöst werden könnten:

  • Statische Ressourcen – OSGi-Bundles, die statische Ressourcen exportieren möchten, registrieren a ResourceLoader Instanzen mit dem Bundle-Kontext.Eine Zentrale ResourceServlet verwendet diese Ressourcenlader, um Ressourcen aus Bundles zu laden.
  • Facelet-Vorlagen – ähnlich wie oben, eine zentrale ResourceResolver nutzt durch Bundles registrierte Dienste.
  • Gemanagte Bohnen - Ich habe keine Ahnung wie man einen Ausdruck wie verwendet #{myBean.property} Wenn myBean ist in einem der Bundles definiert.
  • Servlet-API-Sachen – verwenden Sie etwas wie WebExtender/Pax Web, um Servlets, Filter usw. zu registrieren.

Meine Fragen sind:

  • Erfinde ich hier ein Fahrrad?Gibt es dafür Standardlösungen?Ich habe eine Erwähnung von Spring Slices gefunden, konnte aber nicht viel Dokumentation darüber finden.
  • Glauben Sie, dass OSGi die richtige Technologie für die beschriebene Aufgabe ist?
  • Ist meine Skizze der OSGI-Anwendung mehr oder weniger korrekt?
  • Wie sollen verwaltete Beans (insbesondere Anforderungs-/Sitzungsbereich) behandelt werden?

Generell wäre ich für Ihre Kommentare dankbar.

War es hilfreich?

Lösung

Was Sie vorhaben, klingt machbar, mit ein paar Einschränkungen:

Die Ansichtsebene: Erstens klingt Ihre Ansichtsebene etwas überfüllt.Es gibt andere Möglichkeiten, JSF-Komponenten durch die Verwendung benutzerdefinierter Komponenten zu modularisieren, wodurch die Kopfschmerzen vermieden werden, die mit dem Versuch verbunden sind, etwas so Dramatisches wie verwaltete Beans mit später Bindung zu erstellen.

Die Module selbst: Zweitens scheinen Ihre Module nicht besonders modular zu sein.Ihre erste Aufzählungsliste lässt den Eindruck entstehen, als würden Sie versuchen, interoperable Web-Apps zu erstellen, und nicht Module an sich.Meine Vorstellung von einem Modul ist, dass jede Komponente einen klar definierten und mehr oder weniger diskreten Zweck hat.Zum Beispiel wie ex zugrunde liegt vi.Wenn Sie den OSGi-Weg gehen, sollten wir modular wie folgt definieren: Modular bedeutet im Rahmen dieser Diskussion, dass Komponenten im laufenden Betrieb austauschbar sind – das heißt, sie können hinzugefügt werden und entfernt ohne die App zu beschädigen.

Abhängigkeiten: Ich bin ein wenig besorgt über Ihre Beschreibung der Module als "möglicherweise abhängig voneinander". Sie wissen das wahrscheinlich bereits (ich hoffe) bereits, aber Ihre Abhängigkeiten sollten ein gerichtetes acyclisches Diagramm bilden.Sobald Sie eine zirkuläre Abhängigkeit einführen, kann die Wartbarkeit der App erheblich beeinträchtigt werden.Eine der größten Schwächen von OSGi ist, dass es nicht Verhindern Sie zirkuläre Abhängigkeiten. Es liegt also an Ihnen, dies durchzusetzen.Andernfalls werden Ihre Abhängigkeiten wie Kudzu wachsen und nach und nach den Rest des Ökosystems Ihres Systems ersticken.

Servlets: Fuhgeddaboudit.Sie können Servlets nicht spät in eine Web-App einbinden, nicht bevor die Servlet 3.0-Spezifikation in Produktion ist (wie Pascal betont hat).Um ein separates Dienstprogramm-Servlet zu starten, müssen Sie es in eine eigene App einfügen.


OK, so viel zu den Vorbehalten.Lassen Sie uns darüber nachdenken, wie das funktionieren könnte:

Sie haben Ihr eigenes JSF-Modul definiert, um ...was genau?Geben wir ihm einen definierten, ziemlich trivialen Zweck:ein Anmeldebildschirm.Sie erstellen also Ihren Anmeldebildschirm, binden ihn spätestens mit OSGi in Ihre App ein und ...dann was?Woher weiß die App, dass die Anmeldefunktion vorhanden ist, wenn Sie sie nicht auf Ihrer .jspx-Seite definiert haben?Woher weiß die App, dass sie zu etwas navigieren soll, von dessen Existenz sie nichts weiß?

Es gibt Möglichkeiten, dies zu umgehen, indem Sie bedingte Einschlüsse und ähnliches verwenden (z. B. <c:if #{loginBean.notEmpty}>), aber wie Sie sagten, wird es etwas schwierig, wenn Ihre verwaltete loginBean in einem anderen Modul vorhanden ist, das möglicherweise noch nicht einmal in die App eingeführt wurde.Tatsächlich erhalten Sie eine Servlet-Ausnahme, sofern diese loginBean nicht vorhanden ist.Also, was machst du?

Sie definieren eine API in einem Ihrer Module. Alle verwalteten Beans, die Sie zwischen Modulen gemeinsam nutzen möchten, müssen in dieser API-Schicht als Schnittstellen angegeben werden.Und alle Ihre Module müssen über Standardimplementierungen jeder dieser Schnittstellen verfügen, die sie verwenden möchten.Und diese API muss von allen interoperablen Modulen gemeinsam genutzt werden.Anschließend können Sie OSGi und Spring verwenden, um die angegebenen Beans mit ihrer Implementierung zu verbinden.

Ich muss mir einen Moment Zeit nehmen, um darauf hinzuweisen, dass ich dieses Problem nicht so angehen würde.Gar nicht.Wenn etwas so einfach wie eine Anmeldeseite oder sogar so kompliziert wie ein Aktiendiagramm ist, würde ich persönlich lieber eine benutzerdefinierte JSF-Komponente erstellen.Aber wenn die Anforderung lautet: „Ich möchte, dass meine verwalteten Beans modular sind (d. h. Hot-Swap-fähig usw.),“ ist dies die einzige Möglichkeit, die ich kenne, damit es funktioniert.Und ich bin mir nicht einmal ganz sicher Wille arbeiten. Dieser E-Mail-Austausch deutet darauf hin, dass es sich um ein Problem handelt, an dem JSF-Entwickler gerade erst begonnen haben.

Normalerweise betrachte ich verwaltete Beans als Teil der Ansichtsschicht und verwende sie daher nur für die Ansichtslogik und delegiere alles andere an die Serviceschicht.Meiner Meinung nach bedeutet die späte Bindung verwalteter Beans, sie aus der Ansichtsebene heraus in die Geschäftslogik zu befördern.Es gibt einen Grund, warum sich all diese Tutorials so auf Dienstleistungen konzentrieren:Denn meistens möchten Sie darüber nachdenken, was nötig wäre, damit Ihre App „kopflos“ läuft, und wie einfach es wäre, Ihre Ansicht zu „skinnen“, wenn Sie beispielsweise möchten, dass sie mit all ihren Funktionen läuft. auf einem Android-Telefon.

Aber es hört sich so an, als ob vieles, womit Sie arbeiten, selbst Ansichtslogik ist – zum Beispiel die Notwendigkeit, eine andere Ansichtsvorlage einzutauschen.OSGi/Spring sollte helfen können, aber Sie benötigen etwas in Ihrer App, um zwischen den verfügbaren Implementierungen wählen zu können:so ziemlich das, wofür die Service Registry von OSGi entwickelt wurde.

Dadurch bleiben statische Ressourcen übrig.Sie können diese modularisieren, aber denken Sie daran, dass Sie eine Schnittstelle definieren müssen, um diese Ressourcen abzurufen, und dass Sie eine Standardimplementierung bereitstellen müssen, damit Ihre App nicht abstürzt, wenn sie fehlen.Wenn i18n in Betracht gezogen wird, könnte dies ein guter Weg sein.Wenn du es sein wolltest Wirklich abenteuerlich, dann könnten Sie Ihre statischen Ressourcen in JNDI verschieben.Das würde sie vollständig im laufenden Betrieb austauschbar machen und Ihnen die Mühe ersparen, zu entscheiden, welche Implementierung Sie programmgesteuert verwenden möchten, aber es gibt auch einige Nachteile:Jede fehlgeschlagene Suche führt dazu, dass Ihre App eine NamingException auslöst.Und es ist übertrieben.JNDI wird normalerweise in Web-Apps zur App-Konfiguration verwendet.

Was Ihre verbleibenden Fragen betrifft:

Erfinde ich hier ein Fahrrad?Gibt es dafür Standardlösungen?

Das bist du, ein bisschen.Ich habe Apps gesehen, die das tun Art der Sache, aber Sie scheinen auf eine ziemlich einzigartige Reihe von Anforderungen gestoßen zu sein.

Glauben Sie, dass OSGi die richtige Technologie für die beschriebene Aufgabe ist?

Wenn die Module Hot-Swap-fähig sein sollen, stehen Ihnen OSGi und die leichtere ServiceLocator-Schnittstelle zur Auswahl.

Ist meine Skizze der OSGI-Anwendung mehr oder weniger korrekt?

Ich kann es nicht wirklich sagen, ohne mehr darüber zu wissen, wo Ihre Komponentengrenzen liegen.Im Moment hört es sich so an, als würden Sie OSGi dazu drängen, mehr zu tun, als es leisten kann.

Aber glauben Sie mir nicht beim Wort. ICH gefunden andere Lesestoff an diesen Orten.

Und da Sie nach Frühlingsscheiben fragen, Dies sollte ausreichen, um Ihnen den Einstieg zu erleichtern.Sie benötigen einen Git-Client und es sieht so aus, als würden Sie sich anhand des Quellcodes mit der App vertraut machen.Und es ist ein sehr früher Prototyp-Code.

Andere Tipps

Ich stehe in meinem aktuellen Projekt vor den gleichen Problemen.Meiner Meinung nach ist OSGi die beste und sauberste Lösung im Hinblick auf Standards und zukünftige Unterstützung, aber derzeit könnten einige Probleme auftreten, wenn Sie versuchen, es in einer Webanwendung zu verwenden:

  1. Es gibt noch keine gut integrierte Lösung zwischen einem Webcontainer und der OSGi-Plattform.
  2. OSGi ist möglicherweise zu viel für eine benutzerdefinierte Webanwendung, die nur nach einer einfachen modularisierten Architektur sucht.Ich würde OSGi in Betracht ziehen, wenn mein Projekt Erweiterungen von Drittanbietern unterstützen muss, die nicht zu 100 % unter unserer Kontrolle stehen, wenn das Projekt Hot-Neubereitstellungen, strenge Zugriffsregeln zwischen Plugins usw. benötigt.

Eine benutzerdefinierte Lösung, die auf Klassenladern und Ressourcenfiltern basiert, erscheint mir sehr geeignet.Als Beispiel können Sie das studieren Hudson-Quellcode oder Java Plug-in Framework (JPF)-Projekt (http://jpf.sourceforge.net/).

Was die Erweiterung von web.xml angeht, könnten wir mit der Servlet 3.0-Spezifikation Glück haben (http://today.java.net/pub/a/today/2008/10/14/introduction-to-servlet-3.html# Steckbarkeit und Erweiterbarkeit).

Das von der eingeführte „Webmodul-Bereitstellungsdeskriptorfragment“ (auch bekannt als web-fragment.xml). Servlet 3.0-Spezifikation wäre schön hier.Die Spezifikation definiert es als:

Ein Webfragment ist ein logisches Partitionierung der Web-App in einem solchen die Art und Weise, wie die verwendeten Frameworks innerhalb der Web-App können alle Artefakte, ohne die Entwickler zu bitten, Bearbeiten oder Hinzufügen von Informationen in der web.xml.

Allerdings ist Java EE 6 derzeit möglicherweise keine Option für Sie.Dennoch wäre es die standardisierte Lösung.

Enterprise OSGi ist eine relativ neue Domäne. Glauben Sie also nicht, dass Sie eine Lösung erhalten, die Ihre Anforderungen direkt erfüllt.Eines der Dinge, die meiner Meinung nach bei Equinox (die Osgi-Engine hinter Eclipse und daher eine mit der größten Benutzerbasis!) fehlt, ist ein konsistenter Konfigurations-/DI-Dienst.In meinem Projekt hatten wir kürzlich ähnliche Anforderungen und haben den Aufbau eines einfachen Konfigurations-Osgi-Dienstes abgeschlossen.

Eines der Probleme, die modularen Anwendungen inhärent sein werden, wäre rund um DI, da die Modulsichtbarkeit in einigen Fällen den Klassenzugriff verhindern könnte.Wir haben dies mithilfe einer Richtlinie für registrierte Freunde umgangen, die zwar nicht ganz ideal ist, aber funktioniert.

Abgesehen von der Konfiguration können Sie einen Blick auf das kürzlich veröffentlichte Equinox-Buch werfen, um Anleitungen zur Verwendung von OSGi als Basis für die Erstellung modularer Anwendungen zu erhalten.Die Beispiele mögen spezifisch für Equinox sein, aber die Prinzipien würden mit jedem OSGi-Framework funktionieren.Verknüpfung - http://equinoxosgi.org/

Sie sollten sich Spring DM Server ansehen (er wird derzeit auf Eclipse Virgo umgestellt, wurde aber noch nicht veröffentlicht).Die aktuelle OSGi-Unternehmensspezifikation, die ebenfalls gerade veröffentlicht wurde, enthält viele gute Dinge.

Ich kann mir vorstellen, dass einige der Spring DM-Tutorials hilfreich sein werden.Aber ja, es ist möglich, sowohl Ressourcen als auch Klassen mithilfe der Standardmodularität von außerhalb des Webpakets zu laden.Insofern passt es gut.

Der Sitzungskontext wird so behandelt, wie Sie es in einer Sitzung erwarten würden.Allerdings kann es bei der gemeinsamen Nutzung dieser Sitzung zwischen Webpaketen zu Problemen kommen, sodass Sie nicht sicher sind, ob dies überhaupt möglich ist.

Sie könnten auch versuchen, ein einzelnes Web-Bundle zu haben und dann z.B.die Eclipse-Erweiterungsregistrierung, um die Funktionen Ihrer Web-App zu erweitern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top