Spring 3, Hibernate 4 und Wicket 6: ein starkes Gespann

PrintFriendly and PDF

USA-1328

Ohne Vorkenntnisse ist es gar nicht so einfach, eine Web-Anwendung mit Spring, Hibernate und Wicket aufzusetzen. Dabei reichen dafür nur wenige Zeilen Java-Code.

Im Laufe des Jahre sind im Spring-Framework verschiedene Varianten entstanden, wie man eine Web-Anwendung aufsetzt. Inzwischen ist es möglich, auf externe XML-Konfigurationsdateien vollständig zu verzichten. Wie man konkret vorgeht, eine Spring-Anwendung mit Hibernate und Wicket aufzusetzen, zeigt dieser Artikel.

Im Gegensatz zur JEE 6-Welt muss man sich in der Spring-Welt gleich zu Beginn mit vielen Details beschäftigen, bis die erste Hallo-Welt-Anwendung steht. Dieser Nachteil wird zwar meiner Meinung nach durch die große Flexibilität und die Freiheit, auf einen Applikationsserver verzichten zu können, mehr als wett gemacht. Jedoch muss man sich erst einmal explizit für einen Technologie-Mix entscheiden und dann wissen, wie sich die ausgesuchten Produkte am besten integrieren lassen.

Gerade in der Spring-Welt führen meistens viele Wege zum Ziel, vor allem in der Konfiguration einer Anwendung. War es in den ersten Spring-basierten Anwendungen noch nötig, umfangreiche XML-Dateien zu pflegen, konnten diese durch den Einsatz von Annotationen und besonderen Namespaces in der zweiten Generation deutlich reduziert werden. Seit Spring 3.1 kommt eine Spring-Anwendung nun auch komplett ohne XML aus: Besondere, als @Configuration annotierte Klassen übernehmen die Initialisierung einer Anwendung.

Doch zuerst zur Maven pom.xm-Datei, die alle notwendigen Abhängigkeiten deklariert:

Die Konfiguration einer Spring-Anwendung findet in Klassen statt, die mit der @Configuration-Annotation versehen sind. Die Konfiguration einer Anwendung kann auf mehrere solcher Klassen verteilt werden. Fangen wir mit der Konfiguration von Properties an:

Diese Klasse sucht im Klassenpfad nach einer Datei namens application.properties und stellt alle dort definierten Properties der Anwendung zur Verfügung. Dahinter verbirgt sich das relativ neue Environment-Konzept, das es erlaubt, eine Anwendung relativ leicht und überschaubar für unterschiedliche Umgebungen zu konfigurieren.

Hier ist als Beispiel die referenzierte Konfigurationsdatei mit Einstellungen für eine In-Memory-Datenbank:

Kommen wir zur nächsten Konfigurationdatei, die nun die Dependency-Injection starten und den Zugriff auf die Datenbank konfigurieren soll:

Hier passieren viele Dinge:

  1. Die Konfigurationsklasse für die Properties wird importiert. Anmerkung: Eine getrennte Konfigurationsklasse ist notwendig, damit in dieser Klasse schon das Injection von @Values funktioniert.
  2. Spring wird angewiesen, alle Klassen in den angegebenen Paketen auf Annotationen zu untersuchen. Hier wird festgelegt, dass alle Klassen, die in “backend.*”-Paketen liegen, als Services in Frage kommen.
  3. Spring stellt mehrere “EnableXY”-Annotationen zur Verfügung, um bestimmte Features zu aktivieren. Wenn in einer Anwendung Transaktionsmanagement gewünscht ist, muss es durch @EnableTransactionManagement angestellt werden.
  4. Über die @Value-Annotation erhält man Zugriff auf die Properties der Anwendung.
  5. Hier wird ein einfacher Pool für die Datenbankverbindungen eingerichtet.
  6. In dieser Methode wird Hibernate als JPA-Implementierung konfiguriert, sodass überall in der Anwendung über die Annotation @PersistenceContext eine EntityManager-Instanz erreichbar ist. Spring ermöglicht es, auf die persistence.xml zu verzichten, wenn der Spring-eigenen Klassen-Scanner verwendet wird.
  7. Zusätzlich zur Annotation @EnableTransactionManagement muss ein Transaction-Manager erzeugt werden. Für eine reine Web-Anwendung reicht dazu der JpaTransactionManager von Spring.

Die beiden Konfigurationsklassen alleine reichen noch nicht aus, dass die Spring-Anwendung wirklich hochfährt. Früher war es notwendig, in einer web.xml-Datei z.B. einen Listener zu installieren. Dank der Servlet 3-Spezifikation geht auch dies inzwischen in reinem Java-Code. Die folgende Klasse reicht dazu aus:

Hier kommt viel Spring-Magie zum Tragen. Die wichtige Zeile ist mit (1) markiert; dort wird angegeben, welche Konfigurationsklasse Spring auswerten soll.

Die Konfiguration von Spring und Hibernate ist damit abgeschlossen. Bleibt noch Wicket übrig.

Leider wurde in Wicket 6 der Code auskommentiert, der es erlaubt, auch hier vollständig ohne die web.xml-Datei auszukommen (siehe in der Klasse WicketFilter die Methode getFilterPathFromAnnotation). Dieser Code wird erst wieder in Wicket 7 aktiviert, weil Wicket ansonsten nicht mehr in Java 5 funktionieren würde. Es spricht aber nichts dagegen, den Code in einer abgeleiteten Klasse selbst zu nutzen.

Ansonsten ist es erst einmal noch nötig, Wicket in einer web.xml zu initialisieren:

Hier passiert nicht viel mehr, als dass Wicket angewiesen wird, die Klasse TestWebApplication zu starten. Diese Klasse schaut nun wie folgt aus:

In dieser minimalen Version wird nur die Homepage-Klasse zurückgeliefert und der Adapter zwischen Wicket und Spring eingerichtet. Durch diesen Adapter ist es möglich, in allen Klassen, die von Wickets Component erben, mit der Annotation @SpringBean Zugriff auf alle durch Spring verwaltete Beans zu erhalten.

Damit ist die Web-Anwendung vollständig aufgesetzt und ein Rahmen geschaffen worden, der sich leicht durch weitere Bibliotheken aus dem Spring-Ökosystem erweitern lässt.

Zum Weiterlesen ein paar Tipps: