2009-08-23 2 views
2

Ich arbeite in einer Java EE-Umgebung, in der sich jede Anwendung in einer eigenen WAR-Datei befindet. In der WEB-INF/lib jeder Anwendungs-WAR-Datei befindet sich ein gemeinsames Jar, das von allen Anwendungen gemeinsam genutzt wird. Dieses gemeinsame Jar enthält mehrere Singletons, auf die von vielen Punkten im Code zugegriffen wird. Aufgrund der War-File-Grenzen hat jede Anwendung ihre eigenen Instanzen der Singletons. So arbeiten wir heute, da wir einige Singletons in jeder Anwendung anders konfigurieren wollen.Migrationslösung für Singletons in einer OSGI-Umgebung

Jetzt bewegen wir uns in Richtung einer OSGi-Umgebung, wo diese Lösung nicht mehr funktioniert, da jedes Paket seinen eigenen Klassenlader hat. Wenn ich also versuche, auf MySingleton zuzugreifen, das im Bundle "common.jar" von Bundle "appA. jar "oder aus dem Bundle" appB.jar "Ich werde die gleiche Instanz bekommen.

Denken Sie daran, ich möchte eine andere Instanz eines Singleton pro Bündel "wollen". (so ironisch wie es klingt)

Jetzt ist mir klar, die ideale Lösung wäre, den Code zu reparieren, nicht auf diese Singletons verlassen, aber aufgrund eines engen Zeitplans habe ich mich gefragt, ob Sie eine Art von Migration Lösung vorschlagen können das würde mir erlauben, bündelweite Singletons zu verwenden, so dass jeder von ihnen pro Bündel konfiguriert werden könnte.

Antwort

1

kann ich ein paar Möglichkeiten denken:

  1. eine Kopie aller Klassen in common.jar direkt in dem WAR-Bündel einschließen.
  2. Nest common.jar in jedem WAR Bündel, ändern Sie dann das Bündel Klassenpfad in MANIFEST.MF die verschachtelte jar enthalten: Bundle-ClassPath:., Common.jar
  3. die Singleton Ändern OSGi-Dienste zu verwenden, und die Verwendung eine ServiceFactory, um sicherzustellen, dass jedes anfordernde Paket seine eigene Instanz dieses Service erhält. Sie müssen die Dienstinstanz im Cache zwischenspeichern (nicht verwenden/verwenden/nicht abrufen), um zu vermeiden, dass bei jedem Zugriff eine neue Instanz abgerufen wird.
+0

In Bezug auf Option 2, arbeitet OSGi mit War-Dateien? Ich dachte, OSGi-Bundles sind einfach JAR-Dateien. –

+0

In der OSGi-Spezifikation gibt es nichts, was ein Bundle auf eine Instanz einer JAR-Datei beschränkt. Beispiele für WAR-Unterstützung finden Sie unter Spring DM und OPS4J. – SteveD

2

Ihr Singleton wird ein Service in OSGi sein.

Dann müssen Sie eine ManagedServiceFactory erstellen (siehe zum Beispiel diese article), die für die Registrierung verschiedener Instanzen dieses Dienstes verantwortlich ist; Jeder Dienst wird mit verschiedenen Eigenschaften registriert (f.i.application = "appA" und application = "appB")

Danach greifen Sie auf den richtigen Dienst von jeder Anwendung aus, die eine normale Dienstsuche durchführt und die korrekten Eigenschaften angibt.

+1

Oder hacken Sie den Getter des Singletons, um einen beliebigen Schlüssel (wie den Bundle-Kontext) zu verwenden, mit dem Sie einen Singleton pro Schlüssel zurückgeben können. – SteveD

1

Singletons tatsächlich zu Diensten zuordnen. Wenn die Anwendungen (appA, appB) tatsächlich Bundles sind, implementieren Sie Ihren Dienst als ServiceFactory. Auf diese Weise können Sie für jedes aufrufende Paket automatisch eine separate Instanz zurückgeben. Das ist einfacher als eine ManagedServiceFactory (die für jede Instanz eine explizite Konfiguration benötigt) oder Hacker-Getter.