Kolumne: EnterpriseTales

Version 2.0 der CDI Specification auch in Java SE nutzbar

Lars Röwekamp, Arne Limburg

Bisher ist CDI ein Komponentenframework, das Dependency Injection zur Verfügung stellt, allerdings nur für Java-EE-Anwendungen. Die aktuell gültige Version ist das Maintenance-Release 1.2. Wie wir bereits in der letzten Kolumne berichteten, hat die Spezifizierung von CDI 2.0 aber schon begonnen. Und sie bringt ein durchaus interessantes Feature, mit dem es möglich sein wird, CDI auch außerhalb eines Java-EE-Containers standardisiert zu benutzen. CDI soll in Java SE nutzbar werden. Wir werden in dieser Kolumne vorstellen, wie das API aussehen könnte und was noch fehlt.

Möchte man in einem Java-EE-Container Dependency Injection verwenden, so kann man dies bereits seit Java EE 5 out of the box. Dependency Injection war damals allerdings noch frameworkspezifisch. So gibt es spezielle Annotations, um Dependency Injection in EJB zu verwenden (@Resource und @EJB) und andere, um Dependency Injection in JSF zu erhalten (@ManagedProperty). Erst seit Java EE 6 gibt es mit CDI einen einheitlichen Dependency-Injection-Standard über alle Schichten und Frameworks hinweg. Jedoch ist CDI bisher nur in Java EE verfügbar. Sobald man sich in einem reinen Servlet-Container oder gar einer Swing- oder JavaFX-Anwendung befindet, muss man entweder auf CDI verzichten oder auf implementierungsspezifische APIs zurückgreifen. Das soll sich mit CDI 2.0 ändern.

Dependency Injection in Java SE

Das erste große Dependency-Injection-Framework in Java, das Spring Framework, hatte sich ja bereits zum Ziel gesetzt, keinen schwergewichtigen Container zu benötigen. Es lief seit dem ersten Tag in Java SE. So war es folgerichtig, dass auch der erste Dependency-Injection-Standard JSR-330 (@Inject) als Zielplattform Java SE hat. Gleiches gilt für die zugehörige Referenzimplementierung, Google Guice.

CDI basiert zwar auf @Inject, hatte bisher aber immer Java EE als Zielplattform. Unabhängig davon haben die CDI-Implementierungen aber auch immer die Möglichkeit, in Java SE zu laufen (Weld SE und OpenWebBeans), dann aber mit einem implementierungsspezifischen API.

Eines haben aber alle hier vorgestellten Frameworks gemeinsam: Es gibt bisher keinen standardisierten Weg, sie zu booten. Möchte man also eine CDI-Anwendung starten, muss man auf implementierungsspezifische APIs zurückgreifen. Ein wenig Abhilfe schafft da das Framework DeltaSpike mit CdiCtrl. Hiermit ist es zumindest möglich, Weld und OpenWebBeans mit einem gemeinsamen API zu starten. Möchte man im Projektverlauf also die CDI-Implementierung wechseln, so ändert sich der Startcode nicht.

Containerstart mit CDI 2.0

Ein wichtiger Punkt für das Ziel, CDI in Java SE verfügbar zu machen, ist also das standardisierte API zum Starten des Containers. Da die Version 2.0 der Spezifikation noch nicht final ist, können wir an dieser Stelle noch nicht sicher sagen, wie das API zum Starten eines CDI-Containers aussehen wird, sicher ist aber, dass es eins geben wird. Aller Voraussicht nach wird das Interface CDIProvider um Methoden erweitert, die es ermöglichen, einen Container zu starten und zu stoppen. Das Starten und Stoppen des Containers könnte dann aussehen wie in Listing 1 gezeigt. Ob die Klasse CDI, die von CDIProvider geliefert wird, auch Methoden bekommt, um sich selbst zu starten und/oder zu stoppen, ist noch in der Diskussion.

Listing 1
CDIProvider provider = CDI.getCDIProvider();
if (!provider.isInitialized()) {
    provider.initialize();
}
CDI.current().select(MyBean.class).get().myMethod();
Provider.shutdown();

Scopes in Java SE

Aktuell gibt es auch keine Bestrebungen, in CDI eine Möglichkeit zu schaffen, programmatisch Scopes zu aktivieren oder zu deaktivieren. Der aktuelle Draft der CDI 2.0 Specification sieht vor, dass automatisch der Application-Context (also alle @ApplicationScoped Beans) aktiv ist, wenn der Container gebootet wurde. Weitere aktive Kontexte gibt es in Java SE nicht, und es sind auch bisher keine vorgesehen. Neben dem Schreiben eigener Scopes bleibt aber erneut die Möglichkeit, zu Apache DeltaSpike zu greifen. Diese bereits erwähnte Library ermöglicht das Aktivieren und Deaktivieren von Kontexten über ein einheitliches API (Listing 2).

Listing 2
ContextControl contextControl
    = CDI.current().select(ContextControl.class).get();
contextControl.startContext(RequestScoped.class);
... // request context is active here
contextControl.stopContext(RequestScoped.class);

Fazit

Schon lange gibt es mit @Inject (JSR 330) einen Standard, der Dependency Injection auch in Java SE ermöglicht. Er standardisiert bisher aber noch nicht das Booten des Containers und die Behandlung von Scopes. Gerade die Behandlung von Scopes war schon immer eine Stärke von CDI und steht somit bisher standardmäßig nur in EE-Containern zur Verfügung. Mit CDI 2.0 wird sich das ändern. Die CDI Spec wird auf den Java-SE-Bereich ausgeweitet. Damit können dann alle CDI-Features wie Scoping, Events, Interceptors und Decorators auch in Java SE verwendet werden. Einzig die Möglichkeit, einen Scope programmatisch aktivieren zu können, ist bisher nicht vorgesehen. Hier hilft aber die vorgestellte Bibliothek DeltaSpike mit ihrem ContextControl-Interface. Wer nicht bis CDI 2.0 warten möchte, kann mit DeltaSpike auch bereits jetzt die beiden CDI-Container Weld und OpenWebBeans über ein gemeinsames Interface in Java SE starten. Standardisiert wird das Starten, wie beschrieben, erst mit CDI 2.0. In diesem Sinne: stay tuned.

Geschrieben von
Lars Röwekamp
Lars Röwekamp
Lars Röwekamp ist Gründer des IT-Beratungs- und Entwicklungsunternehmens open knowledge GmbH, beschäftigt sich im Rahmen seiner Tätigkeit als „CIO New Technologies“ mit der eingehenden Analyse und Bewertung neuer Software- und Technologietrends. Ein besonderer Schwerpunkt seiner Arbeit liegt derzeit in den Bereichen Enterprise und Mobile Computing, wobei neben Design- und Architekturfragen insbesondere die Real-Life-Aspekte im Fokus seiner Betrachtung stehen. Lars Röwekamp, Autor mehrerer Fachartikel und -bücher, beschäftigt sich seit der Geburtsstunde von Java mit dieser Programmiersprache, wobei er einen Großteil seiner praktischen Erfahrungen im Rahmen großer internationaler Projekte sammeln konnte.
Arne Limburg
Arne Limburg
Arne Limburg ist Softwarearchitekt bei der open knowledge GmbH in Oldenburg. Er verfügt über langjährige Erfahrung als Entwickler, Architekt und Consultant im Java-Umfeld und ist auch seit der ersten Stunde im Android-Umfeld aktiv.
Kommentare

Schreibe einen Kommentar

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