Verwendung von Spring Boot

Spring und das darauf basierende Spring Boot sind leichtgewichtige, Java-basierte Anwendungsframeworks. Sie implementieren Konzepte wie Inversion of Control (IoC), Dependency Injection (DI) und zahlreiche, häufig benötigte Funktionen, um die Entwicklung von Anwendungen zu beschleunigen.

Spring Beans sind Java-Objekte (POJOs), die durch den IoC Container von Spring instanziiert, konfiguriert und verwaltet werden. Der IoC Container erstellt Spring Beans anhand einer Bean-Definition in Form von Annotationen.

Die folgenden Inhalte beschreiben die allgemeine Nutzung von Spring und Spring Boot für die Umsetzung von Backends und Batches. Die Nutzung spezifischer Features sind Bestandteile der folgenden Bausteine:

1. Vorgaben zur Konfiguration

Das Prinzip Convention over Configuration in Spring Boot vereinfacht die Einrichtung und Entwicklung durch sinnvolle Voreinstellungen.

Starter POMs

Vereinfachte Verwaltung von Abhängigkeiten.

Auto-Konfiguration

Automatische Konfiguration auf der Grundlage der hinzugefügten Abhängigkeiten.

Konfiguration

Externalisierte Konfigurationsdateien in Form von Properties oder YAML.

Eingebetteter Server

Eingebetteter Server (u.a. Tomcat) ohne explizite Einrichtung für die Entwicklung.

1.1. Konfiguration der Applikationsklasse

Der zentrale Ausgangspunkt für die Spring-Konfiguration ist die Applikationsklasse.

Diese wird im Package des Backends oder Batches (<org>.<domäne>.<anwendung>.<it-system>) erstellt.

Die Annotation @SpringBootApplication markiert eine Konfigurationsklasse, die eine oder mehrere @Bean-Methoden deklariert. Darüber hinaus löst sie die automatische Konfiguration sowie das Scannen von Komponenten aus. Die Klasse SpringApplication startet eine Spring-Anwendung aus einer Java-Hauptmethode heraus. Sie erstellt automatisch den Application Context aus dem Klassenpfad, scannt die Konfigurationsklassen und startet schließlich die Anwendung.

Listing 1. Applikationsklasse eines Backends
package de.organisation.bsp.backend;

@SpringBootApplication (1)
public class BspBackend {

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

}
1 Äquivalent zur gleichzeitigen Nutzung von @SpringBootConfiguration, @EnableAutoConfiguration und @ComponentScan.

Ist eine feinere Kontrolle gewünscht, so können mit exclude-Attributen Komponenten von der automatischen Konfiguration ausgeschlossen werden.

Für ein Deployment in einem Servlet-Container muss die Applikationsklasse dem folgenden Listing entsprechen.

Listing 2. Applikationsklasse eines Backends (Servlet-Container)
package de.organisation.bsp.backend;

@SpringBootApplication
public class BspBackend extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(BspBackend.class);
	}

}
Sind mehrere Optionen zum Deployment gewünscht, können die Ansätze kombiniert werden.

1.2. Konfiguration von Schichten

Für jede Schicht wird im entsprechenden Package (<org>.<domäne>.<anwendung>.<it-system>.<schicht>) parallel zu den Interfaces der Komponentenschnittstellen eine mit @Configuration annotierte Konfigurationsklasse erstellt. Externe Klassen, die keine Spring-Annotationen besitzen, werden in der Konfigurationsklasse der Schicht per @Bean-Methoden konfiguriert.

Listing 3. Konfigurationsklasse des Anwendungskerns
package de.organisation.bsp.backend.core;

@Configuration
public class CoreConfig {

    @Bean
    public BeispielBean beispielBean() {
        // ...
    }

}

1.3. Konfiguration von Komponenten

Die Spring Beans der Komponenten werden mit der Annotation @Component oder deren Spezialisierungen wie @Repository, @Service, @Controller und weiteren, je nach Einsatzzweck, versehen. Die Annotation @Component markiert eine Klasse als Spring Bean. Sie wird für jede Klasse verwendet, die als Spring Bean verwaltet werden soll, unabhängig von ihrer Funktion oder Verantwortung.

Es ist gute Praxis, spezifische Ableitungen für Komponenten zu verwenden, um Ihre Absicht klarer auszudrücken und die Codebasis besser zu organisieren.

1.3.1. Annotation @Service

Die Annotation @Service ist eine spezielle Form von @Component. Es ist eine semantische Annotation, die verwendet wird, um Klassen zu kennzeichnen, die Geschäftsfunktionen implementieren.

Die Fachkomponenten des Anwendungskerns werden mit der Annotation @Service ausgezeichnet.

1.3.2. Annotationen @Controller und @RestController

Die Annotation @Controller ist eine Spezialisierung der Annotation @Component. Sie wird typischerweise in Kombination mit annotierten Handler-Methoden verwendet, die auf der Annotation @RequestMapping basieren. Die Annotation @Controller kann nur auf Klassen angewendet werden. Sie wird verwendet, um eine Klasse als Web-Request-Handler zu markieren. Sie wird meist im Kontext von Spring MVC verwendet.

Die Annotation @RestController ist eine "Komfort-Annotation", die selbst mit @Controller und @ResponseBody annotiert ist. Diese Annotation wird verwendet, um eine Klasse als Request-Handler für REST-Endpunkte zu kennzeichnen.

Die Fachkomponenten der Serviceschicht werden mit den Annotationen @Controller und @RestController ausgezeichnet.

1.3.3. Annotation @Repository

Die Annotation Repository ist eine Spezialisierung der Annotation @Component. Sie wird verwendet, um anzuzeigen, dass die Klasse einen Mechanismus für Speicherung, Abruf, Suche, Aktualisierung und Löschung von persistenten Objekten bereitstellt.

Die Fachkomponenten der Persistenzschicht werden dieser Annotation ausgezeichnet.

1.4. Spring Bean Scopes

Der Bean Scope definiert den Lebenszyklus und die Sichtbarkeit einer Bean innerhalb eines Backends oder Batches. Er teilt Spring mit, wie viele Instanzen einer bestimmten Bean erstellt werden sollen und wie lange sie verfügbar sein sollen.

Eine genaue Beschreibung der Scopes bietet die offizielle Spring-Dokumentation.

1.4.1. Instanziierung von Spring Beans minimieren

Der Bean Scope ist so zu wählen, dass eine Spring Bean nicht unnötig oft instanziiert wird. Insbesondere in den Fachkomponenten der Persistenzschicht und des Anwendungskerns sind die meisten Spring Beans deswegen Singletons. In den Fachkomponenten der Serviceschicht gibt es hingegen auch Spring Beans, die im Kontext einzelner HTTP-Anfragen existieren. Sie nutzen den request scope.

2. Vorgaben zur Dependency Injection

Dependency Injection ist in Spring so umgesetzt, dass Spring Beans ihre Abhängigkeiten über Konstruktoren oder Setter-Methoden definieren. Der IoC Container injiziert die passenden Abhängigkeiten während der Erstellung der Spring Beans.

Eine genaue Beschreibung der Dependency Injection bietet die offizielle Spring-Dokumentation.
Verwendung von Dependency Injection

Spring Beans nutzen Konstruktor-basierte Dependency Injection für zwingende Abhängigkeiten und Setter-basierte Dependency Injection für optionale Abhängigkeiten.

Die Auflösung von Spring Beans geschieht im Normalfall im Zuge der Dependency Injection. Dabei sind die folgenden Best Practices zu beachten:

  • Spring Beans werden bevorzugt anhand ihres Typs anstatt ihres Namens aufgelöst. Insbesondere gilt dies für das manuelle Auflösen von Spring Beans über den Application Context.

  • Spring Beans des gleichen Typs können anhand der Annotation @Qualifier oder von Generics voneinander unterschieden werden.

3. Vorgaben zu Spring AOP

Spring AOP ist ein Ansatz, der dabei hilft, übergreifende Belange von fachlichem Code zu trennen. Beispiele hierfür sind Funktionen, die sich über mehrere Module erstrecken, wie Logging, Sicherheit, Transaktionsmanagement und Ausnahmebehandlung. Spring und die IsyFact selbst verwenden Spring AOP genau zu diesem Zweck und bieten den auf ihnen basierenden Anwendungen entsprechenden Mehrwert.

Verwendung von Spring AOP

IT-Systeme verwenden kein Spring AOP zur Implementierung von Fachkomponenten.

Die Nutzung von Funktionen von Spring, Spring Boot und der IsyFact, die auf Spring AOP oder AOP generell beruhen, bleibt davon unberührt. Ebenso können technische Komponenten Spring AOP nutzen.