image
image

Michael Simons ist zweifacher Vater, Ehemann, Geek und leidenschaftlicher Fahrradfahrer. Er entwickelt seit über 15 Jahren Software im Java-Umfeld, davon seit sieben Jahren mit Spring. Michael ist Mitglied des NetBeans Dream Team und Gründer der Euregio JUG. Er schreibt in seinem Blog info.michael-simons.eu über Java, Spring und Softwarearchitektur. Michael arbeitet als Senior Consultant bei innoQ Deutschland.

image

Zu diesem Buch – sowie zu vielen weiteren dpunkt.büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei dpunkt.plus+:

www.dpunkt.plus

Michael Simons

Spring Boot 2

Moderne Softwareentwicklung mit Spring 5

image

Michael Simons

Lektorat: René Schönfeldt

Bibliografische Information der Deutschen Nationalbibliothek

ISBN:

1. Auflage 2018

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.

5 4 3 2 1 0

Inhaltsverzeichnis

Geleitwort

Vorwort

Wege durch das Buch

IEinleitung

1Hallo, Spring Boot

1.1Projektdefinition oder »Project Object Model«

1.2Abhängigkeiten definieren

1.3Hallo, Welt!

1.4Liefern

1.5Fehler erkennen

IISpring Boot

2Projektstruktur

2.1Build-Management-Tools

2.1.1Maven

2.1.2Gradle

2.2Pakete und Klassen strukturieren

2.3Spring Initializr

2.4IDE-Unterstützung

2.4.1Spring Tool Suite

2.4.2NetBeans IDE

2.4.3IntelliJ IDEA

2.4.4Die Qual der Wahl

3Spring-Framework-Grundlagen

3.1Dependency Injection

3.1.1Der Spring-Container

3.1.2Inversion of Control

3.1.3Ausblick

3.2Aspektorientierte Programmierung

3.2.1Einführung

3.2.2Spring und AOP

4Konfiguration

4.1Externe Konfiguration

4.1.1Konfigurationsdateien

4.1.2Zugriff auf Konfiguration

4.2Interne Konfiguration

4.2.1Profile

4.2.2Konfigurationsklassen

4.2.3Automatische Konfiguration

5Die Magie hinter Spring Boot

5.1Grundlagen

5.1.1Namensgebung

5.1.2Factories Loader

5.2Konfiguration, nur unter Bedingung

5.2.1Auf Anwesenheit von Klassen hin testen

5.2.2Auf Anwesenheit von Beans hin testen

5.2.3Die Konfiguration auswerten

5.2.4Weitere Bedingungen nutzen

5.2.5Bedingungen logisch verknüpfen

5.2.6Metadaten bereitstellen

5.2.7Ihren Starter deployen

5.3Fazit

6Logging

6.1Gemeinsame Konfiguration

6.2Erweiterte Konfiguration

6.2.1Logback

6.2.2Log4j 2

6.2.3Java Util Logging (JUL)

6.3Zugriffslogs

6.3.1Tomcat

6.3.2Undertow

6.4Remote-Konfiguration

6.4.1HTTP-Endpunkt

6.4.2JMX

6.5Remote-Logging

7Beschleunigter Entwicklungsprozess mit den devtools

7.1Automatische Neustarts

7.2Automatisches Neuladen von Inhalten

IIIDas Spring-Ökosystem

8Webanwendungen

8.1Spring Web MVC

8.1.1Die Grundlagen verstehen

8.1.2Funktionen kennenlernen

8.1.3Spring Web MVC automatisch konfigurieren

8.1.4Eingebetteten Webcontainer nutzen

8.1.5Statische Inhalte ausliefern

8.1.6JSON-Serialisierung und -Deserialisierung steuern

8.1.7Hochgeladene Dateien verarbeiten

8.1.8Zusätzliche Scopes beherrschen

8.2Template Engines

8.2.1Thymeleaf-Templates nutzen

8.2.2Groovy-Templates verwenden

8.2.3Ausblick

8.3Über WebSockets kommunizieren

8.4JAX-RS nutzen

9Security

9.1Minimale Autokonfiguration

9.2Die Grundlagen verstehen

9.2.1Authentifizierung

9.2.2Autorisierung

9.2.3Spring Security und Spring Web MVC

9.2.4Methodensicherheit

9.2.5Sicherheit auf HTTP-Header-Ebene

9.3Anwendungsbeispiele

9.3.1Die Standardkonfiguration nutzen

9.3.2Methodensicherheit aktivieren

9.3.3Gesicherte URLs und Methoden testen

9.3.4Eine eigene Benutzerverwaltung anbinden

9.3.5Passwörter sicher speichern

9.3.6HTTP-Sicherheit anpassen

9.3.7Form-Login und Webintegration nutzen

9.3.8Spring Data Repositorys absichern

9.3.9OAuth 2 nutzen

9.4Ausblick

10Persistenz

10.1Spring Data

10.2Relationale Datenbanken

10.2.1Datasources

10.2.2Datenbankinitialisierung und -migration

10.2.3Transaktionen

10.2.4Datenbankzugriff

10.3NoSQL-Technologien

10.3.1Spring Data MongoDB

10.3.2Weitere Spring-Data-Module

10.4Fazit

11Caching

11.1Aspekte eines Cache

11.2Deklaratives Caching

11.2.1Caching aktivieren

11.3Caching mit Spring Boot

11.4Beispiele und Sonderfälle

11.4.1Cachen von 3rd-Party-Abhängigkeiten

11.4.2Synchrones Caching

11.4.3Caching von Web-Controller-Methoden

12Messaging

12.1Über JMS kommunzieren

12.1.1JMS-Grundlagen kennen

12.1.2Einen JMS-Broker konfigurieren

12.1.3JmsTemplate und Listener verstehen

12.2AMQP nutzen

12.3Redis als Messaging-System verwenden

12.4Apache Kafka anbinden

12.5Ausblick: Spring Cloud Stream

13E-Mail

13.1Mit Spring Boot E-Mails verschicken

14Reaktive Programmierung

14.1Reactive Streams und Project Reactor

14.2WebFlux-Modul

14.2.1Klassische Annotationen verwenden

14.2.2Datenquellen

14.2.3Funktionales Programmiermodell

14.2.4Reaktive Methoden testen

14.2.5Reaktive Views benutzen

14.2.6Spring Security mit WebFlux verwenden

14.3Ausblick: Spring Cloud Function

15Tests und Dokumentation

15.1Spring-Boot-Starter-Test

15.2Unit-Tests

15.3Integrationstests

15.3.1Grundlage: Das Frameworkmodul »spring-test«

15.3.2Spring-Boot-Anwendungen testen

15.3.3Automatische Mock-Objekte

15.3.4Explizite Tests technischer Schichten

15.3.5Erweiterte Testkonfiguration

15.3.6Hilfsmittel

15.3.7Fazit

16Dynamische JVM-Sprachen und polyglotte Programmierung

16.1Groovy

16.1.1Das Spring-Boot-Commandline-Interface

16.2Kotlin

IVProduktivsetzung

17Actuator

17.1Bereitstellen des Spring Boot Actuator

17.2Übersicht

17.2.1Security

17.2.2Konfiguration der HTTP-Endpunkte

17.2.3Konfiguration der JMX-Endpunkte

17.3Allgemeine Informationen

17.4Health-Status

17.5Metriken mit Micrometer aufzeichnen

17.5.1Verfügbare Metriken

17.5.2Eigene Metriken erfassen

17.5.3Den Metrics-Endpunkt benutzen

17.5.4Metriken exportieren und auswerten

17.6Eigene Endpunkte

18Verteilung

18.1Artefakte

18.2Klassische Installation

18.2.1Als Unix/Linux Service

18.2.2Als Windows-Dienst

18.3Servlet-Container

18.3.1War-Deployment

18.3.2Klassische Spring-Anwendungen migrieren

18.4Verteilung in die Cloud

18.4.1Cloud Foundry

18.4.2Andere Plattformen und Anbieter

VMicroservices mit Spring Cloud: ein Einstieg

19Einführung und Übersicht

19.1Was ist eine Microservice-Architektur?

19.2Was gehört alles zu Spring Cloud?

19.2.1Spring Cloud in Ihr Projekt einbinden

19.3Kontexthierarchien

19.3.1Der Bootstrap-Kontext

19.4Der Wochenplaner: ein verteiltes Beispiel

20Konfiguration in verteilter Umgebung

20.1Den Konfigurationsserver starten

20.2Clients anbinden

21Service Discovery mit Netflix Eureka

21.1Einen Eureka-Server betreiben

21.2Services am Eureka-Server anmelden

21.3Services aus Eureka benutzen

22Circuit Breaker

22.1Spring Cloud Hystrix nutzen

23Weitere Aufgaben lösen

ALebenszyklus von Spring-Anwendungen und Beans

A.1Auf Ereignisse im Lebenszyklus einer Anwendung reagieren

A.2Den Lebenszyklus von Beans verstehen

BErweiterte Konfiguration von Datasources

CUpgrade von Spring Boot 1 auf 2

C.1Spring 5

C.1.1Neue Voraussetzungen: Spring 5 und Java 8

C.1.2Neue Funktionen und Verbesserungen

C.2Änderungen in Spring Boot 2

Glossar

Abkürzungen

Index

Geleitwort

15 Jahre Spring

Die Wurzeln von Spring liegen in einer Sammlung von Framework-Ideen im Buch »J2EE Design and Development« aus dem Jahre 2002 und deren Konkretisierung im Nachfolgebuch »J2EE without EJB« aus dem Jahre 2004. Bücher spielten immer schon eine wichtige Rolle für Spring, sowohl die Titel von meinem Mitgründer Rod Johnson und mir als auch jene aus der Community.

In den 15 Jahren seiner Geschichte entwickelte sich das Spring Framework konsequent weiter, wobei es im Kern des Frameworks nie zu einem radikalen Bruch kam, sondern immer zu einer Evolution im Rahmen des breiteren Java-Ökosystems. Natürlich musste sich das Framework einige Male im sprichwörtlichen Sinne neu erfinden, baute dabei aber jedes Mal wieder auf seinen Kernideen auf und erlaubte das schrittweise Upgrade von Bestandsanwendungen.

Einer der größten Meilensteine in diesen 15 Jahren war sicherlich die Einführung von Spring Boot im Jahre 2014. Ursprünglich gedacht als bequeme Konfigurationsvariante, entwickelte sich Boot schnell zum Standard-Einstiegspunkt ins Spring-Ökosystem und zum beliebtesten Framework für Microservice-Architekturen im Java-Umfeld. Dabei bietet Spring Boot nicht nur einen einfachen Einstieg für Entwickler, sondern auch viele Laufzeit-Features für den Betrieb.

Nach den Feature-Releases 1.1 bis 1.5 bringt Spring Boot 2.0 nun die erste große Überarbeitung, aufbauend auf Spring Framework 5.0. Die Schwerpunktthemen sind dabei breit gefächert: von reaktiver Programmierung bis hin zu Kotlin als neuer Programmiersprache auf der JVM, und nicht zu vergessen natürlich die neuen JDK-Releases der Generation 9+, die uns ab nun zwei Mal im Jahr bevorstehen. Spring Framework 5 und Spring Boot 2 stehen hierfür bereit.

Erfreulicherweise setzt sich auch die Tradition der begleitenden Bücher fort: Michael Simons liefert mit dem vorliegenden Titel nicht nur perfektes Timing, sondern vor allem einen umfassenden Einblick in viele aktuelle Bereiche des Spring-Ökosystems. Dieses Buch deckt alle Facetten der Entwicklung mit Spring Boot ab und bietet einen praktischen Leitfaden für moderne Java-Webanwendungen, der bereits jetzt auf die Herausforderungen der kommenden Jahre ausgerichtet ist.

Viel Spaß bei der Lektüre,

Jürgen Höller
Mitbegründer und Entwicklungsleiter des Spring Framework

Vorwort

Das Spring-Framework

Das Spring-Framework wurde 2002 erstmals als Idee vorgestellt und ein Jahr später unter dem Namen Spring-Framework als quelloffenes Projekt veröffentlicht. Das Ziel – damals wie heute – ist, die Entwicklung mit Java zu vereinfachen und gute Programmierpraktiken zu fördern.

Infrastruktur auf Anwendungsebene ist eines der Schlüsselelemente von Spring. Springs Fokus liegt ganz klar auf Bereitstellung und Konfiguration nichtfunktionaler Anforderungen, so dass Entwickler von Anwendungen sich auf ihre eigentliche Aufgabe, Implementierung der Geschäftslogik, konzentrieren können.

Kernfunktionen von Spring sind dabei:

Der Umfang an Funktionalität ist seit 2003 kontinuierlich gewachsen, die Möglichkeiten, eine Spring-basierte Anwendung zu konfigurieren und in Betrieb zu nehmen, ebenso.

Spring Boot ist in diesem Kontext kein neues Framework, sondern eine Sicht auf die Spring-Platform, die es ermöglicht, eigenständige und produktionsreife Anwendungen auf Basis des beschriebenen Spring-Frameworks zu bauen, die unter anderem folgende Eigenschaften haben:

Warum Spring Boot?

Spring Boot basiert vollständig auf dem Spring-Framework. Es wurde mit dem Ziel erschaffen, die Entwicklung eigenständig lauffähiger Anwendungen mit dem Spring-Framework drastisch zu erleichtern. Convention over configuration sowie wenige, bekannte Annotationen reichen aus, um Artefakte zu erzeugen, die alle benötigten Abhängigkeiten mitbringen und extern konfigurierbar sind. Die Schwelle, mehr als eines dieser Artefakte zu erzeugen und zu verteilen, ist deutlich geringer und Grundlage erfolgreicher Verteilung von Microservices.

Schneller Start

Mit sogenannten »Startern« ist es möglich, die Konfiguration des Builds erheblich zu vereinfachen. Durch Deklaration einer einzigen Abhängigkeit wird zum Beispiel die Unterstützung einer Template-Sprache bereitgestellt, inklusive benötigter Abhängigkeiten und Konfiguration.

Testdriven

Spring Boot bietet herausragende Möglichkeiten, die technischen Schichten einer Anwendung, zum Beispiel Persistenz- und Webschicht, getrennt voneinander zu testen und die Ergebnisse dieser Tests anschließend zu Dokumentationszwecken zu nutzen. Ein nicht unerheblicher Gewinn, um sauberen Code zu schreiben.

Spring Boot liebt Microservices.

Darüber hinaus hat sich um Spring Boot, insbesondere durch die Firma Netflix, ein weiteres Ökosystem an Komponenten aufgetan, das insbesondere auf die Entwicklung verteilter, widerstandsfähiger (»resilient«) Microservices zielt. Machen Sie aber bitte nicht den Fehler und betrachten Spring Boot als »Microservice«-Framework. Sie können mit Spring Boot Teile von Anwendungssystemen auf Basis einer Microservice-Architektur bauen, aber Spring Boot ist deutlich mehr als ein »Microservice«-Framework.

Spring Boot und Cloud-native Java

Im Umfeld von Spring Boot hören Sie oft die Begriffe Cloud-native und 12-Factor-App. Die Firma Pivotal erklärt den Begriff Cloud-native-Anwendungen als Anwendungen, die speziell mit dem Cloud-Modell im Hintergrund entworfen wurden und von kleinen Teams mit Fokus auf einzelnen Features entwickelt, deployt und betrieben werden. Skalierbare Infrastruktur, flexible Zielplattformen, Entwickler, die sich auf Features anstelle von Boilerplate-Code konzentrieren können, und ein Betrieb, der sich am Geschäftsbedarf orientiert, sind heute noch Wettbewerbsvorteile, in naher Zukunft wohl eher Standard. Die folgenden Themen beschreiben Kernaspekte einer Cloud-native-Anwendung:

Die 12-Factor-App als Methode beschreibt Anwendungen, mit denen die Vorteile einer Cloud-native-Umgebung ausgenutzt werden können, und wurde als Manifest unter 12factor.net von Entwicklern der Heroku-Plattform (https://www.heroku.com) in mehreren Sprachen veröffentlicht. Ihr Ziel war es, ideale Praktiken für die Entwicklung von Anwendungen zu schaffen, die wiederkehrende Probleme im Hinblick auf Konfiguration, Portierbarkeit, Verteilung und Skalierung von verteilten Anwendungen verhindern.

Viele Konzepte sind in die Gestaltung von Spring Boot eingeflossen und helfen dabei, Spring Boot zu einer idealen Plattform von Cloud-native-Anwendungen zu machen. Nach der Lektüre des Kapitels können Sie einige der Designentscheidungen Spring Boots besser nachvollziehen. Die Kenntnis der Idee der 12-Factor-Anwendung hilft Ihnen, einige Defaults von Spring Boot besser zu verstehen und sie – falls notwendig – bewusst anders zu konfigurieren.

Einige der Faktoren, die Sie ziemlich klar in Spring Boot wiederfinden, sind:

Eine 12-Factor-App ist noch lange keine »perfekte« Anwendung, und die 12 Faktoren machen erst recht keine Aussage über ein Anwendungssystem, sind aber ein wesentlicher Bestandteil von Cloud-native-Anwendungen. Sie helfen, sowohl die Anwendung selber als auch die Entwicklung ohne wesentliche Änderungen im Tooling und der Architektur zu skalieren, maximale Portierbarkeit zwischen verschiedenen Ausführungsumgebungen zu erreichen und die Kluft zwischen Entwicklung und Produktion zu minimieren.

Warum dieses Buch?

Die Referenzdokumentation von Spring Boot ist ebenso wie die des Spring-Frameworks selber ausgesprochen gut, und es gibt eine Vielzahl von Einführungen für unterschiedliche Themen. Warum also noch ein Buch?

Dieses Buch soll interessierte Entwickler aus dem Java-EE-Bereich ebenso wie Spring-Entwickler ansprechen und ihnen ein »Rezept« an die Hand geben, immer wiederkehrende Aufgaben aus dem fachlichen Alltag elegant und ohne Ablenkung mit Spring Boot zu nutzen.

Spring Boot bringt eine Menge automatischer Konfigurationen für fast alle Aspekte des Spring-Frameworks. Das Buch erklärt diese Magie und hilft dabei, sie für die eigenen Zwecke zu nutzen.

Warum legt das Spring-Boot-Team so viel Wert auf externe Konfiguration? Welchen Vorteil bietet ein Fat Jar? Wie funktionieren die Spring-Boot-Starter? Auch diese Fragen werden beantwortet.

Für wen ist dieses Buch?

Sie sollten grundlegende Kenntnisse der objektorientierten Programmierung besitzen und die Programmiersprache Java einschließlich der Sprachfeatures von Version 8 sowie die funktionalen Erweiterungen verstehen, um diesem Buch folgen zu können.

Spring Boot kann genutzt werden, ohne alle Module des Spring-Frameworks im Detail zu kennen oder vollständig zu verstehen. Ich habe versucht, für dieses Buch einen ähnlichen Kompromiss zu finden: Auch ohne Detailkenntnisse des Spring-Frameworks kennen Sie nach der Lektüre die Philosophie hinter Spring Boot und können damit Anwendungen erstellen. An vielen Stellen bin ich zusätzlich auf grundlegende Konzepte und Ideen des Spring-Frameworks eingegangen, insbesondere im Hinblick auf den Spring-Container, das Web-MVC-Framework und die Datenmodule.

Erfahrene Spring-Entwickler, die bisher noch nicht in Kontakt mit einer Spring-Boot-Anwendung gekommen sind, die unter modernen Gesichtspunkten entworfen wurde, werden überrascht sein, wie leichtfüßig die Entwicklung einer neuen Anwendung mittlerweile vonstatten geht.

Falls Sie bereits eine Vorstellung von Spring Boot und der grundlegenden Konfiguration haben, können Sie mit Kapitel 5 starten. Dort erfahren Sie, wie die automatische Konfiguration funktioniert. In Teil III erfahren Sie, wie Spring Boot bekannte Spring-Funktionen zur Verfügung stellt und wie diese Ihren Zwecken angepasst werden können.

Sie sollten die im Abschnitt »Werkzeuge« auf Seite 10 genannten Tools zur Hand haben, den Umgang mit Maven kennen und die IDE Ihrer Wahl beherrschen.

Autor

Michael Simons ist zweifacher Vater, Ehemann, Geek und leidenschaftlicher Fahrradfahrer. Er entwickelt seit über 15 Jahren Software im Java-Umfeld, seit sieben Jahren mit Spring. Michael ist Mitglied des NetBeans Dream Team und Gründer der Euregio JUG. Er schreibt in seinem Blog info.michael-simons.eu über Java, Spring und Softwarearchitektur. Michael arbeitet als Senior Consultant bei innoQ Deutschland.

Danksagungen

Mein Dank geht sowohl an alle engagierten Probeleser als auch an alle Menschen, die mich moralisch unterstützt haben. Es war mir eine Ehre, mit euch an diesem Buch zu arbeiten:

Andy Wilkinson (@ankinson), Christina Simons (@tinasimons), Eberhard Wolff (@ewolff), Franz van Betteraey (@FrVaBe), Friedel Herten, Dr. Gernot Starke (@gernotstarke), Jörn Hameister (@hameiste), Jürgen Höller (@springjuergen), Lukas Eder (@lukaseder), Mark Paluch (@mp911de), Martin Steinberg (@SbgMartin), Niko Köbler (@dasniko), Rainer Barluschke, Ralf D. Müller (@RalfDMueller), René Schönfeldt, Silke Böhler, Stéphane Nicoll (@snicoll), Tim Riemer (@zordan_f), Yann Cébron (@yanncebron).

Weiterhin konnte ich in dieses Buch die Antworten auf einige Fragen einfließen lassen, die ich auf Twitter, im Slack oder auf Stack Overflow beantwortet habe.

Insbesondere gebührt der ENERKO INFORMATIK in Aachen mein Dank für fantastische 15 Jahre, in denen ich nicht nur interessante Aufgaben hatte, sondern jederzeit Unterstützung erfahren habe, sowohl für alle erdenklichen Projekte als auch in privater Hinsicht.

Dieses Buch jedoch wäre – wie viele andere Dinge in meinem Leben – ohne den Rückhalt meiner Frau Christina unmöglich.

Wege durch das Buch

Sollten Sie zu den Menschen gehören, die jedes Buch von der ersten bis zur letzten Seite lesen, dann betrachten Sie bitte die folgenden Punkte als Hinweis, was ich mir bei der Einteilung des Buches gedacht habe. Ansonsten können sie Ihnen als kleiner Wegweiser durch dieses Buch und das Spring-Ökosystem dienen.

Werkzeuge

Auf Ihrem Weg durch das Buch benötigen Sie mindestens folgende Werkzeuge:

Die drei großen Java-IDEs – Eclipse, NetBeans und IntelliJ IDEA – sind gleichermaßen für die Entwicklung von Spring-Boot-Anwendungen geeignet. Die Beispielprojekte können in allen genannten IDEs geöffnet und bearbeitet werden. Die Unterstützung frameworkspezifischer Funktionen, zum Beispiel die automatische Vervollständigung von Konfigurationseigenschaften, der Support des Spring Boot Initializer start.spring.io und anderer Komfortfunktionen ist teilweise abhängig von der jeweiligen Edition. Folgende Varianten unterstützen die Entwicklung mit Spring Boot sehr gut:

Alle genannten IDEs bringen sowohl integrierte Unterstützung für das Versionsverwaltungswerkzeug git als auch die Build-Tools maven und gradle mit.

Die Beispiele sind in der Regel Maven-Projekte, die den Maven Wrapper beinhalten. Der Maven Wrapper ermöglicht es, Projekte ohne konkrete Maven-Installation sowohl unter einem unixartigen Betriebssystem als auch unter Windows zu bauen: ./mvnw clean install beziehungsweise ./mvnw.cmd clean install. Maven ist ein sehr mächtiges Build-Werkzeug, das in der Vergangenheit mehrfach Kritik für sein komplexes Objektmodell hat einstecken müssen. Sie sollten sich davon allerdings nicht abschrecken lassen: Mit Bedacht eingesetzt, erledigt es die Aufgaben »Dependency Management«, »Bauen von Anwendungen« und »Verteilen von Anwendungen« gut und zum Großteil auch leichtfüßig und fehlerfrei.

Docker

Einige Beispiele dieses Buches setzen Dienste wie Datenbanken, Caches oder Ähnliches voraus. Natürlich kann man die Beispiele nur lesen, es macht aber mehr Spaß, sie auszuprobieren. Docker ist eine Plattform, um Software in sogenannten Containern laufen zu lassen. Viele Produkte, wie MongoDB oder Redis, gibt es in sogenannten Images, die sich nach kurzem Download in einem Container starten lassen.

In den Maven Buildfiles der Beispiele dieses Buches wurden falls nötig diese Images deklariert und zusammen mit der jeweiligen Anwendung so konfiguriert, dass ein ./mvnw docker:run im jeweiligen Projekt ausreicht, um alle externen Dienste passend zum Beispiel zu starten.

Einzige Voraussetzung: Passend für die Plattform der Leser muss Docker installiert und konfiguriert sein. Docker steht unter www.docker.com/products/overview sowohl für Linux, Windows als auch macOS zum kostenfreien Download bereit.

Was ist mit Java 9?

Zum Zeitpunkt der Entstehung dieses Buches und auch von Spring 5 und Spring Boot 2 war Java 9 noch nicht final veröffentlicht. Java 9, beziehungsweise ab März 2018 Java 10, bringt einige tiefgreifende Änderungen mit sich. Es ist die erste modularisierbare Java-Version und schränkt im Zuge dessen den Zugriff auf viele Java-interne Klassen ein. Module ermöglichen eine hohe Kapselung von Code und gehen viel weiter als Accessmodifier von Klassen. Die finalen Versionen von Spring 5 und Spring Boot 2 sind gegen JDK 9 gebaut und getestet. Generell wurde Spring 5 defensiv weiterentwickelt: Aufrufe von deprecated JDK-Klassen wurden vermieden, JDK-Klassen nur beschränkt über Reflection genutzt. Sie werden also grundsätzlich Ihre Spring-Boot-2-Anwendung auf Basis des JDK 9 entwickeln können. Bedenken Sie aber bitte, dass für eine vollständige Kompatibilität einer Anwendung mit Java 9 auch alle Abhängigkeiten Dritter kompatibel sein müssen.

Konventionen

Das vorliegende Buch versucht – genau wie Spring Boot –, Überraschungen zu vermeiden, und befolgt darum einige Konventionen. Alle Beispiele dieses Projektes stehen auf GitHub unter https://github.com/springbootbuch zur Verfügung und können unter der Apache-Lizenz, Version 2.0 genutzt werden.

Innerhalb des vorliegenden Buches werden in den Listings Import-Statements in der Regel weggelassen, sofern die Beispiele auch ohne diese verständlich sind.

Java-8-Features

Die Beispiele machen in der Regel intensiv Gebrauch von Java-8-Features. Dazu gehören nicht nur die Java-8-Stream-API, sondern auch Default-Methoden auf Interfaces, neue Datentypen und insbesondere die Erweiterungen der Reflection-API im Hinblick auf die Ermittlung der Namen von Konstruktor- und Methodenparameter. Die Projekte werden mit dem Javac-8-Flag -parameters übersetzt. Damit stehen die im Code verwendeten Namen für Parameter von Konstruktoren und Methoden über Reflection zur Verfügung. Sie können dadurch von Spring verwendet werden, zum Beispiel innerhalb von Ausdrücken in Form der Spring Expression Language (SpEL). Damit können Sie unter anderem Caching und Methodensicherheit steuern. Spring-Data-Repositorys sind mit den Namen der Parameter in der Lage, Platzhalter in Abfragen zu füllen. Maven-Projekte, die nach den im Buch erklärten Prinzipien erstellt werden, werden automatisch mit diesen Einstellungen kompiliert.

Die Beispiele sind in der Regel so entworfen, dass sie leicht verständlich und leicht zu ändern sind. Sie legen den Fokus auf das behandelte Thema. Komplexe, aufeinander aufbauende Beispiele oder gar ein Beispiel, das alle möglichen Aspekte in einem vereint, sind gerade für Neulinge schwierig nachzuvollziehen und lenken mit aufwendigeren Konfigurationen vom Wesentlichen ab. Spielen Sie ruhig ein wenig mit den Beispielen herum. Beachten Sie, dass Spring Boot zwar ein »opinionated« Framework ist, das heißt, eine starke Meinung zu Dingen hat, aber dennoch schnell aus dem Weg geht: Erkennt es, dass Sie selber Aspekte des Frameworks oder eines Starters konfigurieren oder ersetzen (zum Beispiel eine Datenbankverbindung, Security oder Teile des Web-MVC-Frameworks), wird die automatische Konfiguration abgeschaltet. Die Beispiele haben in der Regel einige Unit-Tests, die das gewünschte Verhalten sicherstellen: Im Zweifelsfall schlagen diese Tests dann fehl.

Welche Versionen von Spring Boot und Abhängigkeiten wurden genutzt?

Alle im Buch gezeigten Beispiele wurden mit Milestone und Release-Candidate-Versionen von Spring Boot 2 entwickelt und schließlich mit der finalen Version getestet. Einige Beispiele nutzen explizit neue Funktionen von Spring Boot 2 und werden nicht mit älteren Versionen funktionieren. Alle weiteren Abhängigkeiten werden in den Versionen genutzt, die die Spring Boot Bill Of Materials (BOM, siehe Abschnitt 1.1) vorgibt. Solange Sie also in Ihren eigenen Beispielen explizit andere Versionen für Abhängigkeiten angeben, sollten die Beispiele auch für Ihre Projekte funktionieren.

Die Spring-Boot-Referenz unter https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/reference ist gut zu lesen und zusammen mit der tiefergehenden Spring-Framework-Referenz unter https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference wichtig für eine erfolgreiche Arbeit mit Spring Boot.

Teil I

Einleitung

1Hallo, Spring Boot

Für den Einstieg in die Entwicklung mit Spring Boot eignet sich wie in vielen anderen Fällen auch eine einfache Hallo, Welt!-Anwendung. Diese Anwendung wird ausreichen, etliche Schlüsselfeatures von Spring Boot zu erklären. Das Ziel der einfachen Anwendung ist, einen Endpunkt zu entwickeln, der über HTTP veröffentlicht wird und per GET aufgerufen werden kann. Dieser Endpunkt soll Hello, ${name} zurückgeben, wobei name einem übergebenen Parameter entspricht.

1.1Projektdefinition oder »Project Object Model«

Quelltext

helloworld steht auf GitHub zur Verfügung: https://github.com/springbootbuch/helloworld. Wie alle Beispielprojekte in diesem Buch stellt der Inhalt des Repositorys den »Endzustand« des Projektes nach dem entsprechenden Kapitel dar, der Text führt Sie also quasi durch die Entstehung des Projektes.

Viele der in diesem Buch genutzten Beispiele beinhalten unterschiedliche Profile (siehe Unterabschnitt 4.2.1). Unterschiedliche Profile ermöglichen es, Ihnen mehrere Alternativen zur Lösung einer Aufgabe nebeneinander in einem Projekt vorzustellen und durch Wahl des entsprechenden Profils beim Start einer Anwendung auszuführen. In »echten« Projekten sollten Sie einige der Kombinationen sicherlich vermeiden und sich für eine der Alternativen entscheiden.

Wie im Abschnitt »Werkzeuge« auf Seite 10 erläutert, werden Java und Maven vorausgesetzt. Jetzt ist der richtige Zeitpunkt gekommen, zu prüfen, ob beide verfügbar sind:

java -version

mvn -v

Listing 1–1Java- und Maven-Installation prüfen

Beide Befehle sollten Informationen über Java und Maven ausgeben. Spring Boot 2.0 setzt mindestens Java 8 voraus, und Maven sollte in der Version 3+ genutzt werden.

Maven-Projekte werden über das sogenannte POM, das »Project Object Model«, in der Datei pom.xml definiert:

<?xml version="1.0" encoding="UTF-8"?>

<project

xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation=

"http://maven.apache.org/POM/4.0.0

imagehttp://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.0.0.RELEASE</version>

</parent>

<groupId>de.springbootbuch</groupId>

<artifactId>helloworld</artifactId>

<version>0.0.1-SNAPSHOT</version>

</project>

Listing 1–2pom.xml

Dieses POM resultiert bereits in einem funktionierenden Build, das entstehende JAR ist allerdings leer. Bekannt sind an dieser Stelle nur die »Koordinaten« des Projektes (geschrieben als "groupId:artifactId" lauten sie "de.springbootbuch:helloworld") und ein »Parent«-POM:

Das POM des Beispiels folgt der offiziellen Empfehlung, vom POM spring-boot-starter-parent zu erben. Dieses Maven-Projekt hat den Typ pom und beschreibt damit eine Projektstruktur, von der andere Projekte erben können.

Vererbungsstrukturen in Maven-Projekten erlauben viele nützliche Dinge, von denen die Verwaltung von Abhängigkeiten, das sogenannte Dependency Management1, sicherlich am nützlichsten ist. Jedes Spring Boot Release stellt eine Menge kuratierter Abhängigkeiten zur Verfügung. Die Abhängigkeiten beinhalten sowohl alle Spring-Module, die offiziell mit Spring Boot nutzbar sind, als auch eine Menge an Bibliotheken von Drittherstellern. Die Abhängigkeiten auf dieser »Bill of Materials« (BOM) sind in dieser Konstellation getestet worden und funktionieren miteinander.

Für Abhängigkeiten, die Teil der BOM sind, müssen also keine Versionsangaben getätigt werden.

spring-boot-starter-parent bringt folgende zusätzliche Defaults in das Projekt:

Diese Einstellungen – wie auch die Versionen der Abhängigkeiten – können mit Propertys überschrieben werden. Spring Boot 2 setzt allerdings Java 8 voraus, Java 6 und 7 werden nicht mehr unterstützt. Sofern Sie Java 6 oder 7 benutzen müssen, können Sie nur Spring Boot <= 1.5.x einsetzen.

1.2Abhängigkeiten definieren

Die Abhängigkeiten eines Maven-Projektes können ohne IDE mit mvn dependency:tree aufgelistet werden:

[INFO] Scanning for projects...

[INFO]

[INFO] -----------------------------------------------------

[INFO] Building helloworld 0.0.1-SNAPSHOT

[INFO] -----------------------------------------------------

[INFO]

[INFO] --- maven-dependency-plugin:2.10:tree (default-cli)

@helloworld ---

[INFO] de.springbootbuch:helloworld:jar:0.0.1-SNAPSHOT

[INFO] -----------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] -----------------------------------------------------

[INFO] Total time: 3.303 s

[INFO] Finished at: 2018-03-15T16:23:18+01:00

[INFO] Final Memory: 17M/309M

[INFO] -----------------------------------------------------

Listing 1–3spring-boot-starter-parent selber hat keine Abhängigkeiten.

Es werden nun zwei Abhängigkeiten deklariert: org.springframework.boot:spring-boot-starter-test und org.springframework.boot:spring-boot-starter-web, der erstgenannte im Scope test:

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

</dependencies>

Listing 1–4Abhängigkeiten fürs Testen und Entwickeln

spring-boot-starter-parent nutzt Mavens Dependency Management. Dabei werden in einem zentralen POM Abhängigkeiten und ihre Versionen gepflegt, ohne sie tatsächlich als solche zu deklarieren. Werden die Abhängigkeiten dann in Projekten, die von diesem Parent-POM erben, konkretisiert, kann auf die Angabe von Versionsnummern verzichtet werden. Würden diese Versionsnummern im <version />-Element der Abhängigkeit angegeben, so würde eine entsprechende Warnung im Log erscheinen. Sollen Versionen überschrieben werden, so muss dies mit Propertys geschehen.

org.springframework.boot:spring-boot-starter-web hängt ab vom Starter spring-boot-starter-tomcat und mit diesem unter anderem von org.apache.tomcat.embed:tomcat-embed-core: Die Anwendung, die hier erstellt wird, beinhaltet also bereits einen eingebetteten Webcontainer, der vollständig konfiguriert ist und per Default auf Port 8080 horcht. Es muss also kein dedizierter Container aufgesetzt werden, um eine Spring-Boot-Anwendung zu verteilen, und die Anwendung kann direkt gestartet werden. In Unterabschnitt 8.1.4 wird beschrieben, wie der eingebettete Container konfiguriert, angepasst oder ein anderer Container als Apache Tomcat genutzt werden kann.

1.3Hallo, Welt!

Zu diesem Zeitpunkt ist das Projekt immer noch leer. Die Deklaration von org.springframework.boot:spring-boot-starter-test hat unter anderem transitive Abhängigkeiten zum Testsupport von Spring Boot und Spring sowie natürlich zu JUnit 42. Abschnitt 15.1 geht im Detail auf diese Abhängigkeiten ein.

Hallo, Welt kann damit also vollständig testgetrieben entwickelt werden. Testgetrieben heißt, dass Sie zuerst Code schreiben, der das erwartete Ergebnis überprüft, und erst dann das eigentliche Programm. Es wird ein erster Test im Verzeichnis src/test/java angelegt. src/test/java ist das Standardverzeichnis von Maven für Testklassen:

@RunWith(SpringRunner.class)

@WebMvcTest

public class ApplicationTest {

@Autowired

private MockMvc mockMvc;

@Test

public void helloWorldShouldWork() throws Exception {

this.mockMvc

.perform(

get("/hello").param("name", "World"))

.andExpect(status().isOk())

.andExpect(

content().string("Hello, World\n"));

}

}

Listing 1–5ApplicationTest.java

Details dieses Tests werden ausführlich im Kapitel 15 »Tests und Dokumentation« besprochen. Durch @RunWith(SpringRunner.class) wird festgelegt, dass ein spezialisierter JUnit Runner zur Ausführung des Tests genutzt wird. @WebMvcTest legt fest, dass ausschließlich Komponenten getestet werden, die in den Bereich Spring MVC fallen. Mit der Instanzvariable mockMvc können schließlich URLs dieser Komponenten getestet werden. Im Beispiel heißt das konkret: »Der Aufruf der URL ’/hello’ mit Request-Parameter name=World soll den HTTP Status 200 haben und den Inhalt ’Hello, World’ zurückgeben.«. Dabei ist der sogenannte Test-Slice @WebMvcTest »intelligent« genug, nicht den vollständigen, eingebetteten Servlet-Container zu starten und stattdessen eine »Mock«-Umgebung zu nutzen.

Der Test wird ausgeführt mit mvn test und schlägt leider fehl. Der korrekte Rootcause lautet: »Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=…) with your test«.

Der Test kann keinen Spring-Kontext finden und konfigurieren, es gibt ihn aktuell nicht. Ein gültiger Spring-Kontext wird durch die Klasse Application.java in Listing 1–6 definiert. In wenigen Zeilen Code passieren bereits etliche interessante und wichtige Dinge:

package de.springbootbuch.helloworld;

import org.springframework.boot.SpringApplication;

import

imageorg.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class Application {

public static void main(String... args) {

SpringApplication.run(Application.class, args);

}

}

Listing 1–6Application.java

Meta- oder Composed-Annotationen

Im Spring-Sprachgebrauch werden Meta- und Composed-Annotationen unterschieden. Als Meta-Annotation wird eine Annotation, die auf einer weiteren Annotation verwendet wird, bezeichnet. Eine Meta-Annotation erweitert die ursprüngliche Annotation um zusätzliche, beschreibende Eigenschaften. Die daraus entstandene Composed-Annotation kann wie eine reguläre Annotation auf entsprechende Ziele (Klasse, Methoden, Parameter etc.) angewandt werden.

Auslöser ist die zusammengesetzte (composed) Annotation @SpringBoot-Application, die folgende Annotationen kombiniert:

@SpringBootConfigurationZentrale Konfiguration einer Spring-Boot-Anwendung. Spring-Boot-Anwendungen sollten maximal eine @SpringBootConfiguration-Annotation beinhalten. Sie ist eine Spezialisierung der @Configuration des Spring-Frameworks selber, die zentraler Bestandteil der Java-basierten Konfiguration ist.

@EnableAutoConfigurationorg.apache.tomcat.embed:tomcat-embed-coreTomcatServletWebServerFactory