Autokonfiguration in Spring Boot

„Any technology, no matter how primitive, is magic to those who don’t understand it.“

Florance, from Freefall

Eines der interessantesten Features von Spring Boot bemerkt man immer erst dann, wenn es mal nicht da ist. Im Beitrag Frontend Validierung mit Spring Boot (Teil 2) habe ich ein kleinen Framework vorgestellt, das man in eigene Applikationen einbinden kann. Mein Erstaunen war groß, als es gleich beim ersten Mal nicht funktionierte.

Ursprünglich habe ich das Framework innerhalb eines anderen Projekts entwickelt und dort auch getestet. Innerhalb dieser Spring Boot Applikation wurden natürlich alle Komponenten gefunden, initialisiert und gestartet. Nachdem ich die entsprechenden Klassen ausgegliedert und dabei die Package Namen geändert hatte, wurden die Komponenten nicht mehr gefunden.

Für solche Situationen stellt Spring Boot den Auto-Configuration Mechanismus bereit. Dieser Mechanismus lädt besondere Konfigurationsklassen, die dann Komponenten für spezielle Systemkonfigurationen bereitstellen. Beispielsweise stellt Spring Boot eine Auto-Configuration Klasse fur die H2 Datenbank bereit. Wird die H2 Bibliothek ins Projekt eingebunden, kann diese automatisch verwendet werden.

Damit das Spring Boot Frontend Projekt automatisch eingebunden wird, benötigen wir also erst einmal eine Konfigurationsklasse.

@Configuration
@ConditionalOnClass(ExecutableValidator.class)
@Import({ HibernateConfiguration.class, ValidationsConfiguration.class, 
  UriValidatorConfiguration.class, FrontendEndPoint.class })
@EnableConfigurationProperties(FrontendProperties.class)
public class FrontendAutoConfiguration {
}

Auf dem ersten Blick etwas wenig Klasse und dafür etwas viel Annotationen. Die erste Annotation teilt Spring Boot mit, dass es sich hier um eine Konfiguration handelt. Die zweite Annotation aktiviert diese Konfiguration nur, wenn die Klasse javax.validation.executable.ExecutableValidator im Classpath liegt, also tatsächlich JSR 380 Support im Projekt existiert. Die dritte Annotation importiert drei weitere Konfigurationen und unseren eigentlichen EndPoint.

Die drei Konfigurationen stellen die Unterstützung für JSR380, Hibernate und URI Validator bereit.

@Configuration
@ConditionalOnClass(Localhost.class)
public class UriValidatorConfiguration {
  @Bean("uri-validator")
  AnnotationFeature getFeature() {
    return new UriValidationFeature();
  }
}

Die Konfigurationsklasse UriValidatorConfiguration wird beispielsweise nur dann instantiiert, wenn die Klasse Localhost aus der Uri Validator Bibliothek im Classpath zu finden ist.

Die letzte Annotation aus der Auto-Configuration Klasse lädt noch eine Property zur weiteren Konfiguration der Ausgabe. Damit kann über die applications.properties oder application.yaml angegeben werden, ob die JSR380 Messages eingefügt werden sollen oder nicht.

Damit wären alle Vorbereitungen abgeschlossen, aber damit Spring Boot unsere Konfigurationsklasse findet müssen wir noch eine Kleinigkeit einfügen. Spring Boot sucht in den Bibliotheken nach einer Datei META-INF/spring.factories, die unter anderen den Eintrag org.springframework.boot.autoconfigure.EnableAutoConfiguration enthalten kann. Dort tragen wir alle unsere Auto-Configuration Klassen ein.

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  de.schegge.frontend.FrontendAutoConfiguration

Fügen wir die Bibliothek jetzt zu einem bestehenden Projekt hinzu, wird unser Actuator Endpoint automatisch konfiguriert und instantiiert.