Leitfaden für @ConfigurationProperties im Spring Boot

Anleitung zu @ConfigurationProperties in Spring Boot

1. Einführung

Eine praktische Funktion von Spring Boot istexternalized configuration and easy access to properties defined in properties files. In einem früherenarticlewurden verschiedene Möglichkeiten beschrieben, wie dies durchgeführt werden kann.

Wir werden nun die Annotation von@ConfigurationPropertiesgenauer untersuchen.

Weitere Lektüre:

Eine Kurzanleitung zu Spring @Value

Erfahren Sie, wie Sie mit der Anmerkung Spring @Value Felder aus Eigenschaftendateien, Systemeigenschaften usw. konfigurieren.

Read more

Eigenschaften mit Feder und Spring Boot

Lernprogramm zum Arbeiten mit Eigenschaftendateien und Eigenschaftswerten in Spring.

Read more

2. Konfiguration

Dieser Artikel verwendet ein ziemlich Standardsetup. Wir beginnen mit dem Hinzufügen vonspring-boot-starter-parent als übergeordnetes Element in unserenpom.xml:



    org.springframework.boot
    spring-boot-starter-parent
    2.1.3.RELEASE
     

Um die in der Datei definierten Eigenschaften überprüfen zu können, benötigen wir außerdem eine Implementierung von JSR-303. hibernate-validator ist einer von ihnen.

Fügen wir es auch zu unserenpom.xmlhinzu:


   org.hibernate
   hibernate-validator
   6.0.16.Final

Die Seitegetting started with Hibernate Validatorenthält weitere Details.

3. Einfache Eigenschaften

In der offiziellen Dokumentation wird empfohlen, die Konfigurationseigenschaften in separate POJOs.zu isolieren

Beginnen wir also damit:

@Configuration
@PropertySource("classpath:configprops.properties")
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {

    private String hostName;
    private int port;
    private String from;

    // standard getters and setters
}

Wir verwenden@Configuration, damit Spring im Anwendungskontext eine Spring Bean erstellt.

Wir verwenden auch@PropertySource, um den Speicherort unserer Eigenschaftendatei zu definieren. Andernfalls verwendet Spring den Standardspeicherort (classpath:application.properties).

@ConfigurationProperties works best with hierarchical properties that all have the same prefix. Also fügen wir ein Präfix vonmail hinzu.

Das Spring-Framework verwendet Standard-Java-Bean-Setter. Daher ist es wichtig, dass wir für jede Eigenschaft Setter deklarieren.

Hinweis: Wenn wir@Configuration in nicht im POJO verwenden, müssen wir@EnableConfigurationProperties(ConfigProperties.class) in in der Hauptanwendungsklasse von Spring hinzufügen, um die Eigenschaften in das POJO zu binden:

@SpringBootApplication
@EnableConfigurationProperties(ConfigProperties.class)
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Das ist es! Spring will automatically bind any property defined in our property file that has the prefix mail and the same name as one of the fields in the ConfigProperties class.

Spring verwendet einige entspannte Regeln für die Bindungseigenschaften. Die folgenden Variationen sind also alle an die EigenschafthostName gebunden:

mail.hostName
mail.hostname
mail.host_name
mail.host-name
mail.HOST_NAME

Wir können die folgende Eigenschaftendatei verwenden, um alle Felder festzulegen:

#Simple properties
[email protected]
mail.port=9000
[email protected]

4. Verschachtelte Eigenschaften

Wir können verschachtelte Eigenschaften inLists, Maps, undClasses. haben

Erstellen wir eine neueCredentials-Klasse, die für einige verschachtelte Eigenschaften verwendet werden soll:

public class Credentials {
    private String authMethod;
    private String username;
    private String password;

    // standard getters and setters
}

Wir aktualisieren auch die KlasseConfigProperties, umList, aMap und die KlasseCredentials zu verwenden:

public class ConfigProperties {

    private String host;
    private int port;
    private String from;
    private List defaultRecipients;
    private Map additionalHeaders;
    private Credentials credentials;

    // standard getters and setters
}

Die folgende Eigenschaftendatei legt alle Felder fest:

#Simple properties
[email protected]
mail.port=9000
[email protected]

#List properties
mail.defaultRecipients[0][email protected]
mail.defaultRecipients[1][email protected]

#Map Properties
mail.additionalHeaders.redelivery=true
mail.additionalHeaders.secure=true

#Object properties
mail.credentials.username=john
mail.credentials.password=password
mail.credentials.authMethod=SHA1

5. Verwenden von@ConfigurationProperties bei einer@Bean-Methode

Wir können auch die Annotation@ConfigurationProperties für Methoden mit@Bean-Annotation verwenden.

Dieser Ansatz kann besonders nützlich sein, wenn wir Eigenschaften an eine Komponente eines Drittanbieters binden möchten, die außerhalb unserer Kontrolle liegt.

Erstellen wir eine einfacheItem-Klasse, die wir im nächsten Beispiel verwenden werden:

public class Item {
    private String name;
    private int size;

    // standard getters and setters
}

Lassen Sie uns nun sehen, wie wir@ConfigurationProperties für eine@Bean-Methode verwenden können, um externalisierte Eigenschaften an dieItem-Instanz zu binden:

@Configuration
public class ConfigProperties {

    @Bean
    @ConfigurationProperties(prefix = "item")
    public Item item() {
        return new Item();
    }
}

Auf diese Weise wird jede Eigenschaft mit Elementpräfix der InstanzItemzugeordnet, die vom Spring-Kontext verwaltet wird.

6. Eigenschaftsüberprüfung

@ConfigurationProperties provides validation of properties using the JSR-303 format. Dies ermöglicht alle möglichen netten Dinge.

Lassen Sie uns beispielsweise die EigenschafthostNameobligatorisch machen:

@NotBlank
private String hostName;

Und die EigenschaftauthMethodist 1 bis 4 Zeichen lang:

@Length(max = 4, min = 1)
private String authMethod;

Und die Eigenschaft vonportvon 1025 bis 65536:

@Min(1025)
@Max(65536)
private int port;

Schließlich muss die Eigenschaftfrommit einem E-Mail-Adressformat übereinstimmen:

@Pattern(regexp = "^[a-z0-9._%+-][email protected][a-z0-9.-]+\\.[a-z]{2,6}$")
private String from;

Dies hilft uns, vieleif – else-Bedingungen in unserem Code zu reduzieren und lässt ihn viel sauberer und prägnanter aussehen.

If any of these validations fail then the main application would fail to start with an IllegalStateException.

Das Hibernate Validation-Framework verwendet Standard-Java-Bean-Getter und -Setter. Daher ist es wichtig, dass wir Getter und Setter für jede der Eigenschaften deklarieren.

7. Immobilienkonvertierung

@ConfigurationPropertiesunterstützt die Konvertierung für mehrere Typen, um die Eigenschaften an die entsprechenden Beans zu binden.

7.1. Duration

Wir beginnen mit der Konvertierung von Eigenschaften inDuration Objekte.

Hier haben wir zwei Felder vom TypDuration:

@ConfigurationProperties(prefix = "conversion")
public class PropertyConversion {

    private Duration timeInDefaultUnit;
    private Duration timeInNano;
    ...
}

Und unsere Eigenschaftendatei:

conversion.timeInDefaultUnit=10
conversion.timeInNano=9ns

Infolgedessen hat das FeldtimeInDefaultUnit einen Wert von 10 Millisekunden undtimeInNano einen Wert von 9 Nanosekunden.

Die unterstützten Einheiten sindns, us, ms, s, m, h undd für Nanosekunden, Mikrosekunden, Millisekunden, Sekunden, Minuten, Stunden bzw. Tage.

Die Standardeinheit ist Millisekunden. Wenn wir also keine Einheit neben dem numerischen Wert angeben, konvertiert Spring den Wert in Millisekunden.

Wir können die Standardeinheit auch mit@DurationUnit: überschreiben

@DurationUnit(ChronoUnit.DAYS)
private Duration timeInDays;

und die entsprechende Eigenschaft:

conversion.timeInDays=2

7.2. DataSize

In ähnlicher Weise unterstützt Spring Boot@ConfigurationProperties die Typkonvertierung vonDataSize.

Fügen wir 3 Felder vom TypDataSizehinzu:

private DataSize sizeInDefaultUnit;

private DataSize sizeInGB;

@DataSizeUnit(DataUnit.TERABYTES)
private DataSize sizeInTB;

und die entsprechenden Eigenschaften:

conversion.sizeInDefaultUnit=300
conversion.sizeInGB=2GB
conversion.sizeInTB=4

In diesem Fall beträgt der Wert vonsizeInDefaultUnit300 Byte, da die Standardeinheit Byte ist.

Die unterstützten Einheiten sindB, KB, MB, GB undTB.. Wir können die Standardeinheit auch mit@DataSizeUnit. überschreiben

7.3. BenutzerdefinierteConverter

Wir können auch unsere eigenen benutzerdefiniertenConverterhinzufügen, um die Konvertierung einer Eigenschaft in einen bestimmten Klassentyp zu unterstützen.

Fügen wir eine einfache KlasseEmployee hinzu:

public class Employee {
    private String name;
    private double salary;
}

Und wir erstellen einen benutzerdefinierten Konverter, um diese Eigenschaft zu konvertieren:

conversion.employee=john,2000

zu einem Feld vom TypEmployee:

private Employee employee;

Wir müssen dieConverter-Schnittstelle implementieren, dannuse @ConfigurationPropertiesBinding annotation to register our custom*Converter*:

@Component
@ConfigurationPropertiesBinding
public class EmployeeConverter implements Converter {

    @Override
    public Employee convert(String from) {
        String[] data = from.split(",");
        return new Employee(data[0], Double.parseDouble(data[1]));
    }
}

8. Fazit

Wir haben die Annotation von@ConfigurationPropertiesuntersucht und einige der praktischen Funktionen wie entspanntes Binden und Bean-Validierung gesehen.

Wie üblich ist der Codeover on Github verfügbar.