Spring Time

Eclipse 4 Dependency Injection mit dem Spring Framework

Lars Vogel und Felix Heppner

Eclipse 4 basiert auf dem neuen Programmiermodell der Dependency Injection. Hierbei nutzt Eclipse einen eigenen Dependency Injection Container. Was aber, wenn der Kunde schon das Spring Framework zur Definition von OSGi Services nutzt? Muss man jetzt alles neu definieren? Wir zeigen, wie leicht sich OSGi Services, definiert mit Spring DM (OSGi Blueprint Services), in Eclipse 4 integrieren lassen.

Zum Thema Dependency Injection und Eclipse 4 gab es ja schon viele Artikel im Eclipse Magazin. Das Ganze ist im Prinzip trivial: Es gibt einen hierarchischen IEclipseContext, der die Werte beinhaltet, die injiziert werden können (Abb. 1). Die Suche, etwa eines Parts, führt immer nach oben.

Abb. 1: EclipseContext-Hierarchie

Die oberste Stufe des hierarchisch angelegten EclipseContext ist die OSGi-Service-Schicht. Deklariert man hier OSGi Services, z. B. basierend auf dem IMyService-Interface, kann man sich Letzteres in die Klassen, die im Applikationsmodell referenziert werden, injizieren lassen:

// Field Injection
@Inject IService myservice

Für Eclipse 4 ist es irrelevant, wie diese OSGi Services deklariert wurden. Man kann diese via Programmcode oder via OSGi Declarative Services deklarieren. Oder eben auch mit Spring DM.

Was sind Spring bzw. Blueprint Services?

Sowohl Spring DM als auch OSGi Blueprint Services sind Hilfsmittel zur deklarativen Erzeugung und Verwendung von OSGi Services. Spring DM 1.x war die erste Spring-Variante eines APIs, die von der Notwendigkeit entbunden hat, programmatisch Instanzen der OSGi Services zu veröffentlichen bzw. zu konsumieren. Besonders die OSGi-inhärente Dynamik war mit dem Spring API einfacher – und vor allem mit weniger und nicht OSGi-spezifischem Code – zu behandeln.

Unter dem Einfluss von Spring DM entstand der OSGi-Standard für Blueprint Services. Dieser Standard definiert in der OSGi-Spezifikation in Version 4.2, wie Blueprint Services mittels einer Referenz in der MANIFEST.MF-Datei und einer zusätzlichen XML-Konfigurationsdatei zu deklarieren sind.

Da OSGi nur eine Spezifikation ist, benötigt man eine Referenzimplementierung. Spring DM 2.x wurde die Referenzimplementierung zu Blueprint Services. Um die deklarative Konfiguration von Services auszuwerten, verwendet Spring DM einen OSGi Extender [1]. Der Extender für Blueprint Services untersucht alle OSGi Bundles im Zustand STARTED. Er wartet auf die entsprechenden Bundle Events der OSGi Runtime und erzeugt dann den so genannten Application Context für die relevanten Bundles. Ein Application Context in Spring ist – vereinfacht ausgedrückt und analog zu einem IEclipseContext – ein Container für Objekte (Beans). Beans sind Instanzen von Objekten, die wiederum andere Beans aus demselben Application Context injiziert bekommen oder anderen Beans injiziert werden können.

Der Application Context erzeugt Beans aus Bean Definitions, die in den meisten Fällen aus XML-Dokumenten gelesen werden. Diese XML-Dateien können durch zusätzliche Namespaces und Handler erweitert werden, und genau das geschieht durch Spring DM. Mit dem „normalen“ Beans Namespace werden die Beans z. B. durch das Erzeugen von Klasseninstanzen oder aber auch durch Factories erzeugt. Zu den Details und zusätzlichen Möglichkeiten, etwa für Remoting und Proxies, beispielsweise für Transaktionen, sei hier auf die Spring-Dokumentation verwiesen.

Durch die Verwendung des DM oder auch des Blueprint Namespaces werden Proxies für OSGi Services erzeugt, die dann für andere Beans als „normale“ Beans zur Injektion zur Verfügung stehen. Oder es werden Exporter erzeugt, die wiederum „normale“ Beans injiziert bekommen und diese als OSGi Service exportieren. So werden die OSGi Services, die gemäß der Konfiguration importiert wurden, den anderen Beans im Application Context verfügbar gemacht. Die exportierten Beans stehen als OSGi Services für andere Bundles bereit.

Man kann damit also Spring Application Context und den OSGi Context verbinden. Eine Konfiguration wird immer dann gefunden, wenn unterhalb des META-INF-Verzeichnisses ein Verzeichnis mit dem Namen spring existiert und dieses mindestens eine .xml-Datei enthält (Konvention osgi-context.xml). Über den Header „Spring-Context“ in der MANIFEST.MF kann die Position der XML-Konfiguration auch auf einen beliebigen anderen Pfad im Bundle geändert werden. In der MANIFEST.MF-File können noch weitere Einstellungen getroffen werden, z. B. wait time für benötigte Services oder die synchrone bzw. asynchrone Application-Context-Erzeugung.

Geschrieben von
Lars Vogel und Felix Heppner
Kommentare

Schreibe einen Kommentar

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