2 CDI
2.1 Was ist das?
CDI steht für„Contexts and Dependency Injection for the Java EE Platform“ und ist ein Standard innerhalb des Webprofils der Dachspezifikation Java EE. Der Arbeitsbereich von CDI ist die Bereitstellung und Verknüpfung von Komponenten und Diensten als Basis für Enterprise-Applikationen. CDI ist allerdings nicht nur im EE-Umfeld nutzbar, sondern kann auch ohne Applikationsserver eingesetzt werden.
CDI 1.0 wurde im JSR 299 lange Zeit unter den Namen WebBeans entworfen und standardisiert viele Ideen und Konzepte von populären Open-Source-Frameworks wie Seam und Spring(-Core). Die aktuelle Version 1.1 (JSR 346) hat eine für Java-EE-Verhältnisse angenehm kurze Spezifikation: ca. 130 gut lesbare Seiten1.
Neben der Referenzimplemtierung JBoss Weld2 stehen u. a. Apache OpenWebBeans3 und Resin CanDI4 als CDI-Container zur Verfügung.
2.2 Wozu braucht man das?
Professionelle Anwendungen sind nicht monolithisch aufgebaut, sondern bestehen aus Komponenten. Zum einen ergeben sich bei der Entwicklung von Software aus der Analyse der Aufgabenstellung fachliche Bereiche, die durch fachliche Komponenten abgebildet werden können. Innerhalb dieser Komponenten lassen sich wieder Teile abgrenzen, diesmal eher technischer Natur. Die Komponenten benutzen andere Komponenten sowie die Plattformdienste, sind aber weitgehend abgegrenzt (Abb. 2.1).
Abbildung 2.1: Anwendungskomponenten
Eine Aufgabe der Softwareentwicklung ist es nun, diese Komponenten untereinander zu verknüpfen, sodass eine saubere Anwendungsarchitektur entsteht. Das kann natürlich mit einfachen Sprachmitteln von Java geschehen: Eine Komponente kann in ihrem Programmcode andere Komponenten instanziieren, indem sienew benutzt. Dadurch wird die Kopplung der Komponenten aber sehr stark: Die aufrufende Komponente muss die benutzte sehr genau kennen,Änderungen sind aufwändig, der Einsatz einer alternativen Komponente ist unmöglich.
Zudem profitieren solche Objekte kaum von der Umgebung der Anwendung: Der Applikationsserver„kennt“ sie nicht, kann also bspw. kein Monitoring und keine Laufzeitsteuerung dafür durchführen. Flexibler ist es, die benötigten Objekte vom Application Server herstellen zu lassen. In den früheren Versionen der Java EE– damals noch J2EE– hat man dazu weitgehend String-basierte Referenzen benutzt, hat also bspw. die benötigte Komponente per Namen im JNDI-Dienst adressiert. Hier stellt sich aber das Problem der„Zielgenauigkeit“: Ist ein Objekt unter dem verwendeten Namenüberhaupt vorhanden und hat es den richtigen Typ (Listing 2.1)?
// Unsicher: Ist ein Objekt mit dem Namen konfiguriert?
// Falls ja, hat es den korrekten Typ?
MyService myService
= (MyService) jndiContext.lookup("ejb/myService");
Listing 2.1: Referenzierung einer Komponenteüber ihren Namen
Ein weiteres Problem ist die Abhängigkeit der aufrufenden Komponente von ihrer Umgebung: Der Code im Beispiel setzt unumstößlich voraus, dass es e