Modulare Enterprise-OSGi-Anwendungen mit Eclipse Gemini

Warum nicht DI ohne Blueprint?

Machen wir einen kleinen Exkurs zu Dependency Injection jenseits von Blueprint. Die wichtigste Alternative zu Blueprint sind Declarative Services (DS), die ebenfalls Teil der OSGi-Enterprise-Spezifikation [4] sind. Der Ansatz von DS ist dem von Blueprint ähnlich. DS nutzt XML-Konfigurationsdateien, in denen angegeben wird, welche Services konsumiert oder veröffentlicht werden. Diese Services werden dann auch per Dependency Injection injiziert. Ein wichtiger Unterschied ist jedoch, dass sich DS nur mit öffentlichen Services beschäftigt. Klassen innerhalb eines Bundles können DS nicht nutzen. Für Tests bleibt bei DS nur die Variante mit Mock-Objekten, da es keinen Support für Tests bietet. Ob einem Blueprint oder DS besser gefällt, hängt viel von den eigenen Vorlieben und Erfahrungen ab. Im Eclipse-Umfeld sind DS weit verbreitet, alle die schon mit Spring gearbeitet haben, werden sich bei Blueprint heimisch fühlen. Auch wenn Blueprint und DS zwei Alternativen mit ähnlicher Zielsetzung sind, können sie problemlos miteinander kombiniert werden. Schade ist jedoch, dass der OSGi-Enterprise-Standard mit diesen konkurrierenden Technologien für eine Fragmentierung gesorgt hat. Ob das langfristig von Vorteil ist, bleibt abzuwarten.

DI in unserem Beispielprojekt

Jetzt wollen wir Gemini Blueprint in Action sehen. Dazu schauen wir auf unser Beispielprojekt [1]. Es nutzt Dependency Injection mit Gemini Blueprint:

  • um Services zu publizieren
  • um Services zu konsumieren
  • um Beans innerhalb eines Bundles zu erzeugen und zu verdrahten
  • für Tests

Was ist nun zu tun, um Gemini Blueprint in einem Bundle zu nutzen? Dazu braucht es zum einen eine Blueprint-Konfiguration und zum anderen die Abhängigkeit zum Blueprint Bundle. Die Konfiguration ist stets in der XML-Datei META-INF/spring/bundle-context.xml abgelegt. Die Abhängigkeit zum Blueprint Bundle wird im OSGi Manifest angegeben, wie in Listing 7 gezeigt.

Listing 7
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: PE Console Commands
Bundle-SymbolicName: com.pe-international.sample.console
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: PE-INTERNATIONAL
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: com.pe_international.sample.repository,
 model.account,
 org.eclipse.gemini.blueprint;version="1.0.0.RELEASE",
 org.eclipse.osgi.framework.console;version="1.1.0"

Zur Laufzeit werden die Bundles von Gemini Blueprint und Spring benötigt. Gemini Blueprint benötigt die Bundles blueprint-core, blueprint-extender und blueprint-io. Von Spring brauchen wir mindestens core, beans, context, expression, asm und aop. Unser Beispielprojekt braucht noch ein paar zusätzliche Bundles für den Zugriff auf die Datenbank. Greifen wir uns das Bundle com.pe-international.sample.repository.jpa.manual als Beispiel heraus. Das Bundle enthält eine Implementierung des Interface CustomerRepository. Als Basis werden die JPA Bundles aus dem vorherigen Artikel genutzt. Die Blueprint-Konfiguration des Bundles zeigt Listing 8.

Listing 8

Das Bundle konsumiert den EntityManager-Service der JPA Persistence Unit Accounts. Dazu wird die Referenz auf den EntityManager-Service im Element reference deklariert und mittels Filter auf die Persistence Unit Accounts eingeschränkt. Die Implementierung des CustomerRepository-Interface wird als Service publiziert. Dazu wird im Element service die Bean mit der Implementierung referenziert und das Interface, das diese implementiert, wird automatisch als Service veröffentlicht. Die Transaktionen werden deklarativ über Spring gesteuert. Dazu wird ein TransactionManager erzeugt und die Implementierung des CustomerRepositorys verwendet die Spring-Annotationen für Transaktionen. Die Tests dieses Bundles liegen in dem separaten Bundle com.pe-international.sample.repository.jpa.manual.test, das ein Fragment des Bundles mit der Repository-Implementierung ist. Dort ist auch der Test der Repository-Implementierung zu finden, der gegen eine In-Memory-Datenbank läuft.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.