Überblick Spring Context and Dependency Injection
Mit Spring Context and Dependency Injection wurde 2003 ein Framework eingeführt, der JEE damals in vielen Bereichen überlegen war. Die grundsätzlichen Ideen wurden zwar größtenteils in den aktuellen Versionen Spezifikation nachgezogen, trotzdem bleibt Spring bis heute umfangreicher. Dieser Vorteil wird zwar durch eine Bindung an ein proprietäres Framework bezahlt, aber viele Architekten sind bereit, diese Konsequenz zu akzeptieren.
Spring Context and Dependency Injection unterstützt drei unterschiedliche Technologien:
- XML
- Annotations
- Java Config
Diese können jederzeit untereinander beliebig gemischt werden.
XML
Die Definition der CDI-Objekte mit XML war der ursprüngliche Ansatz, der von der Spring Community gewählt wurde. Hierzu werden die Spring Beans in einer XML-Datei abgelegt:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <bean class="org.javacream.books.warehouse.impl.MapBooksService" id="mapBooksService" scope="singleton"> <property name="isbnGenerator" ref="randomIsbnGenerator" /> <property name="storeService" ref="simpleStoreService" /> </bean> <bean class="org.javacream.books.isbngenerator.impl.RandomIsbnGenerator" id="randomIsbnGenerator" scope="singleton" init-method="initGenerator" destroy-method="destroyGenerator"> <property name="prefix" value="${isbngenerator.prefix}" /> <property name="countryCode" value="${isbngenerator.countryCode}" /> </bean> <bean class="org.javacream.store.impl.SimpleStoreService" scope="singleton" id="simpleStoreService" p:stock="${storeService.stock}" /> <context:property-placeholder location="bookswarehouse.properties" /> </beans>
Mit XML können Anwendungen sehr elegant und kompakt definiert werden. Allerdings wird zur Unterstützung eine komplexe IDE wie IntelliJ oder die Spring Tools Suite benötigt. Sonst werden elementare Operationen der Software-Entwicklung wie Refactoring oder Code-Assistenten nicht unterstützt.
Annotations
Mit der Einführung der Annotationen mit Java 5 wurde die Definition der Spring Beans auch direkt aus dem Java Code heraus möglich. Dazu wurde ein Satz von Spring-spezifischen Annotations-Typen eingeführt:
@Component
@Service
@Repository
Diese Typen sind im stereotype
s-Paket definiert und ermöglichen deshalb eine sinnvolle Gruppierung und Dokumentation der Anwendungs-Klassen. Prinzipiell würde die@Component
-Annotation genügen.
Die Annotations-basierte Definition ist bei den Anwendungs-Programmieren sehr beliebt und wird in vielen Projekten bevorzugt benutzt.
Java Config
Dies ist der bisher neueste Ansatz, Spring Beans zu definieren. Hierzu wird eine mit @Configuration
annotierte Klasse eingeführt, welche mit@Bean
annotierte Factory-Methoden enthält. Der Spring-Kontext instanziert die diese Klasse und ruft diese Method je nach Bedarf auf. Wichtig ist hierbei, dass die @Configuration
-Klasse sowie die Factory-Methoden selber ebenfalls wieder Dependencies aufweisen dürfen. Ein einfaches Beispiel ist hier noch gegeben:
package org.javacream; import org.javacream.books.isbngenerator.api.IsbnGenerator; import org.javacream.books.isbngenerator.impl.RandomIsbnGenerator; import org.javacream.books.warehouse.api.BooksService; import org.javacream.books.warehouse.impl.MapBooksService; import org.javacream.store.api.StoreService; import org.javacream.store.impl.SimpleStoreService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ApplicationConfiguration { @Bean public BooksService booksService() { MapBooksService booksService = new MapBooksService(); booksService.setIsbnGenerator(isbnGenerator()); booksService.setStoreService(storeService()); return booksService; } @Bean public IsbnGenerator isbnGenerator() { RandomIsbnGenerator isbnGenerator = new RandomIsbnGenerator(); isbnGenerator.setPrefix("JAVA-ISBN"); isbnGenerator.setCountryCode("-is"); return isbnGenerator; } @Bean public StoreService storeService() { SimpleStoreService storeService = new SimpleStoreService(); storeService.setStock(42); return storeService; } }
Java Config scheint zwar ein Rückschritt zu sein, da nun ja wieder der Entwickler selber den Lebenszyklus der Fachobjekte übernimmt. Allerdings stehen auch hier die weiteren Spring-Features zur Verfügung, so dass dieser Ansatz eine durchaus sinnvolle Ergänzung ist.
Zusammenspiel mit Spring Boot
Spring Context and Dependeny Injection wird selbstverständlich komplett von Spring Boot unterstützt. Ohne weitere Konfiguration werden automatisch alle Pakete unterhalb und inklusive des Application-Hauptpakets nach Klassen mit Spring-Annotationen durchforstet und analysiert. Für das Einbinden einer XML-Konfiguration kann @ImportResource
benutzt werden.