Eigene Properties im Banner

Ein nettes Feature von Spring Boot ist der standardmäßige Banner in der Logausgabe nach dem Start der Anwendung. Der nachfolgende Banner zeigt nicht die übliche ASCII Art, sondern wurde auf schegge.de abgeändert. Außerdem wurden, neben der verwendeten Spring Boot Version, noch der Startzeitpunkt und der Autor der Anwendung ausgegeben.

            _                                       _
           | |                                     | |
 ___   ___ | |__    ___   __ _   __ _   ___      __| |  ___
/ __| / __|| '_ \  / _ \ / _` | / _` | / _ \    / _` | / _ \
\__ \| (__ | | | ||  __/| (_| || (_| ||  __/ _ | (_| ||  __/
|___/ \___||_| |_| \___| \__, | \__, | \___|(_) \__,_| \___|
                          __/ |  __/ |
                         |___/  |___/

Spring Boot Version: 2.2.4.RELEASE
Startup Time:        26.02.20, 10:34
Author:              Jens Kaiser

Der Banner kann, wie vieles andere in Spring Boot auch, auf unterschiedlicheste Weise konfiguriert werden. Die einfachste Art ist die Nutzung einer angepassten banner.txt Datei. In ihr ist der gesamte Banner dargestellt und dynamische Inhalte über Platzhalter eingefügt.

            _                                       _
           | |                                     | |
 ___   ___ | |__    ___   __ _   __ _   ___      __| |  ___
/ __| / __|| '_ \  / _ \ / _` | / _` | / _ \    / _` | / _ \
\__ \| (__ | | | ||  __/| (_| || (_| ||  __/ _ | (_| ||  __/
|___/ \___||_| |_| \___| \__, | \__, | \___|(_) \__,_| \___|
                          __/ |  __/ |
                         |___/  |___/

Spring Boot Version: ${spring-boot.version}
Startup Time:        ${startup}
Author:              ${info.app.author}

Wie man sieht, wird für die Ausgabe der Spring Boot Version, die vordefinierte Property spring-boot.version verwendet. Die anderen beiden Properties, info.app.author und startup, sind eher unbekannt.

Bevor wir näher auf die Properties eingehen, möchte ich zunächst ein weiteres hilfreiches Feature im Zusammenhang mit den Banner vorstellen.

In den application.properties kann auch der Name der verwendeten Banner Datei konfiguriert werden. Üblicherweise lautet er banner.txt. Da es möglich ist, für unterschiedliche Profile eigene Properties Dateien zu verwenden, kann also der Name des Banner Profil-spezifisch gewählt werden. Für die Entwicklungsumgebung z.B. banner-dev.txt.

# application-dev.properties
spring.banner.location=classpath:/banner-dev.txt

Diese Banner Datei kann völlig anders definiert sein und Informationen bereitstellen, die nur während der Entwicklungszeit interessieren.

===========
DEVELOPMENT
===========
${git.branch}

Die Property git.branch interessiert normalerweise nicht auf der Produktion, weil dort hoffentlich immer nur Artefakte aus dem Main- oder Produktions-Branch verwendet werden.

Wie kommen aber nun eigene Properties in die banner.txt Datei hinein? Erst einmal stehen alle Properties zur Verfügung, die im Spring Boot Environment vorhanden sind. Die info.app.author Property können wir der application.properties hinzufügen.


info.app.name=Ancestor Demo
info.app.description=An ancestor REST endpoint
info.app.version=1.0.0
info.app.author=Jens Kaiser

Die ersten drei Properties sind standardmäßig in Spring Boot vorhanden und werden hier nicht ganz grundlos gezeigt. Der Info-Actuator in Spring Boot zeigt alle Properties mit dem Präfix info an. Unsere eigene Property info.app.author erscheint also nicht nur im Banner, sondern auch in der Ausgabe des Info-Actuator.

Etwas schwieriger wird es mit der Property startup, weil sie kein fest definierter Wert ist, sondern erst beim Start der Applikation bestimmt werden kann. Wir müssen also den Wert berechnen und in das Environment einfügen.

Das Environment enthält die Properties in PropertySources Instanzen organisiert. Die einzelnen Property Sourcen sind u.a. das System Environment, die Application Properties und diverse andere Quellen. Um eine eigene Property im Environment bereitzustellen, ist es am einfachsten eine eigene Property Source mit der eigenen Property zu erstellen und dnn diese Source in das Environment einzufügen.

Mit einem eigenen EnvironmentPostProcessor, kann das Environment nach der Erstellung noch modifiziert werden. Für unser Beispiel fügen wir eine MapPropertySource in das Einvironment ein. Die MapPropertySource enthält, wie der name der Klasse vermuten lässt, die Properties als Map.

public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {
  public static void addStartUpProperties(ConfigurableEnvironment environment) {
    environment.getPropertySources().addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
        new MapPropertySource("demo", Map.of("startup", LocalDateTime.now())));
  }

  @Override
  public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
    addStartUpProperties(environment);
  }
}

Ein EnvironmentPostProcessor muss bei Spring Boot angemeldet werden, damit er seine Arbeit verrichtet. Er beginnt ja seine Arbeit noch bevor irgendwelche Componenten das Licht der Welt erblicken. Im Beitrag Autokonfiguration in Spring Boot haben wir schon einmal dieses Mechanismus verwendet. In der Datei META-INF/spring.factories benotigen wir folgenden Eintrag

org.springframework.boot.env.EnvironmentPostProcessor=\
de.schegge.demo.CustomEnvironmentPostProcessor

Auf diese Weise lassen sich alle möglichen Properties in die eigene Applikation einfügen und an unterschiedlichsten Stellen nutzen.