~/blog/2013/09/spring-boot-ausprobiert-spring-ohn.md

Spring Boot ausprobiert: Spring ohne Konfiguration?

4 min
Titelbild: Spring Boot ausprobiert: Spring ohne Konfiguration?

Keine Zeit? Hier die Kurzversion in 30 Sekunden.

  • Spring Boot wurde im August angekündigt und liegt als Milestone (0.5.0.M) vor, noch nicht final.
  • Ein Starter-POM, eine Klasse mit @EnableAutoConfiguration und eine main-Methode genügen für eine laufende Webanwendung mit eingebettetem Tomcat.
  • Konfiguration über application.properties; per Groovy-CLI reicht sogar eine einzelne Datei.
  • Gegenüber der XML-Konfiguration von früher ein großer Schritt, aber vieles passiert unsichtbar.
  • Mein Urteil: vielversprechend, doch als Milestone nichts für Produktion, APIs können sich noch ändern.

Wer vor ein paar Jahren eine Spring-Webanwendung gebaut hat, kennt die Reihenfolge: web.xml, ein DispatcherServlet, eine Kontextdatei mit Bean-Definitionen, Component-Scan, View-Resolver, und erst danach die erste Zeile Fachlogik. Ich habe 2010 selbst über die Neuerungen von Spring 3 geschrieben und war damals froh über jede Annotation, die ein Stück XML ersetzte. Jetzt hat das Spring-Team Spring Boot vorgestellt, und der Anspruch ist, dass man all das gar nicht mehr schreibt. Ich habe mir die aktuellen Milestone-Versionen (0.5.0.M) angesehen.

Das Minimum

Ausgangspunkt sind die Starter-POMs. Statt zehn einzelne Abhängigkeiten mit passenden Versionen zusammenzusuchen, bindet man eine ein:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>0.5.0.M4</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

Die Versionsnummer muss man an die jeweils aktuelle Milestone anpassen, außerdem braucht es das Milestone-Repository des Projekts, denn in Maven Central liegt das noch nicht. spring-boot-starter-web zieht Spring MVC, Jackson und einen Tomcat zum Einbetten nach. Dazu kommt eine einzige Klasse:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@EnableAutoConfiguration
public class Beispiel {

    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hallo Welt";
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Beispiel.class, args);
    }
}

Ein Start der main-Methode, und unter http://localhost:8080/ antwortet die Anwendung. Es gibt keine WAR-Datei, keinen Servlet-Container zum Installieren und keine XML-Datei. @EnableAutoConfiguration schaut in den Klassenpfad, erkennt Spring MVC und Tomcat und richtet passende Beans ein. Das ist der Kern der Idee. Man bekommt nicht ein Framework, das weniger kann, sondern eines, das sinnvolle Voreinstellungen mitbringt und sich zurückhält, sobald man selbst etwas vorgibt. Ob diese Voreinstellungen im Alltag so gut passen, wie sie in der Ankündigung wirken, wird sich an größeren Projekten zeigen.

Konfiguration und Groovy

Was sich anpassen lässt, steht in einer application.properties im Klassenpfad. Der Port ist ein Beispiel:

server.port=9090

Eigene Beans haben Vorrang: Definiert man selbst einen Datenquellen- oder View-Resolver-Bean, zieht sich die Autokonfiguration an der Stelle zurück. Das ist sinnvoll und der Teil, der mich am meisten überzeugt, denn so bleibt man nicht in einer Box gefangen.

Ganz ohne Maven geht es mit der Kommandozeile, die man separat herunterlädt. Eine Datei app.groovy:

@Controller
class Beispiel {
    @RequestMapping("/")
    @ResponseBody
    String home() {
        "Hallo Welt"
    }
}

Dann spring run app.groovy, und es läuft. Imports und Abhängigkeiten werden anhand der verwendeten Annotationen ergänzt. Für Experimente und kleine Werkzeuge ist das erstaunlich bequem. Ob ich einen echten Dienst so schreiben würde, ist eine andere Frage, denn hier passiert am meisten im Verborgenen.

Der Vergleich mit früher

Die klassische Variante hatte den Vorteil, dass alles sichtbar war. Wer wissen wollte, warum eine Bean existiert, fand sie in der XML-Datei. Das war mühsam, aber nachvollziehbar. Bei Spring Boot ist die Frage „Woher kommt das?“ schwerer zu beantworten, wenn die Magie hinter einer Annotation steckt. Ich sehe die Gefahr, dass man einen laufenden Prototyp bekommt, den man ohne Kenntnis des Frameworks nicht mehr versteht, wenn etwas nicht wie gedacht funktioniert. Wer Spring ohnehin kennt, wird das Ganze eher als Abkürzung nutzen, und für diese Gruppe ist es sehr gut. Einsteigern würde ich raten, vorher einmal die Konfiguration von Hand gesehen zu haben.

Interessant finde ich auch den eingebetteten Container. Anwendung als einfaches Java-Programm mit main-Methode zu starten und zu betreiben, nimmt viel Reibung aus Entwicklung und Test. Der Gedanke ist nicht neu, Jetty lässt sich schon lange einbetten, aber hier ist es das Standardverhalten und nicht ein Bastelprojekt.

Pro und Contra

Für Boot spricht aus meiner Sicht vor allem die Zeit bis zum ersten laufenden Stand. Ein neues Projekt ist in Minuten startklar, ohne dass man erst eine Vorlage aus dem letzten Projekt kopiert und von Altlasten befreit. Auch die Versionsverwaltung der Abhängigkeiten gefällt mir: Wenn der Parent die zusammenpassenden Versionen von Spring, Jackson und Tomcat festlegt, entfällt eine typische Fehlerquelle, nämlich die Bibliothek, die zum Rest nicht passt.

Dagegen spricht, dass man sich an ein Gesamtpaket bindet. Wer für eine Anwendung eine ältere Bibliotheksversion braucht oder einen anderen Container einsetzen möchte, muss gegen die Voreinstellungen arbeiten. Dazu kommt, dass Teams, die den Betrieb auf klassische WAR-Dateien in einem zentralen Anwendungsserver ausgelegt haben, mit einer selbst startenden Anwendung erst einmal wenig anfangen können. Das ist keine Kritik an Boot, es zeigt nur, dass Entwicklung und Betrieb dabei zusammen reden müssen.

Meine Einschätzung

Spring Boot ist die richtige Richtung. Das Framework hat sich mit der Zeit zu einem Konfigurationsberg entwickelt, und hier räumt jemand auf, ohne die Grundlagen auszutauschen. Für neue kleine Dienste und Prototypen werde ich es weiter ausprobieren.

Produktiv würde ich es dennoch nicht einsetzen. Es ist ein Milestone, die Versionsnummer beginnt mit 0.5, und Paketnamen, Annotationen und Eigenschaften können sich bis zum Release noch ändern. Wer jetzt Code darauf aufbaut, muss mit Anpassungen rechnen. Ich beobachte die Entwicklung, schaue mir die nächsten Milestones an und prüfe dann, ob aus dem vielversprechenden Versuch ein verlässliches Werkzeug geworden ist.

Beitragsbild: eigene Collage mit Logos von Wikimedia Commons (Spring-Logo: Pivotal Software, CC BY-SA 2.0); die Marken gehören ihren Inhabern. Die Collage steht ebenfalls unter CC BY-SA 2.0.

$ whoami
Christian Ackermann

Softwareentwickler (C++, C, Java, C#) aus der Oberpfalz, bloggt seit 2001 über Linux, Technik und Kochen.