Guide til @ConfigurationProperties i Spring Boot

1. Introduktion

Spring Boot har mange nyttige funktioner, herunder eksternaliseret konfiguration og nem adgang til egenskaber defineret i egenskabsfiler. En tidligere tutorial beskrev forskellige måder, hvorpå dette kunne gøres.

Vi skal nu udforske @ConfigurationProperties kommentar mere detaljeret.

2. Opsætning

Denne tutorial bruger en ret standard opsætning. Vi starter med at tilføje spring-boot-starter-parent som forælder i vores pom.xml:

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

For at kunne validere egenskaber, der er defineret i filen, har vi også brug for en implementering af JSR-303 og dvale-validator er en af ​​dem.

Lad os tilføje det til vores pom.xml såvel:

 org.hibernate hibernate-validator 6.0.16.Final 

Siden "Kom godt i gang med dvaletilstand" har flere detaljer.

3. Enkle egenskaber

Den officielle dokumentation anbefaler, at vi isolerer konfigurationsegenskaber i separate POJO'er.

Så lad os starte med at gøre det:

@Configuration @ConfigurationProperties (præfiks = "mail") offentlig klasse ConfigProperties {private String hostName; privat int port; privat streng fra; // standard getters og setter}

Vi bruger @Konfiguration således at Spring skaber en Spring bønne i applikationskonteksten.

@ConfigurationProperties fungerer bedst med hierarkiske egenskaber, som alle har samme præfiks; derfor tilføjer vi et præfiks på post.

Spring-rammen bruger standard Java-bønnesættere, så vi skal erklære settere for hver af egenskaberne.

Bemærk: Hvis vi ikke bruger @Konfiguration i POJO, så skal vi tilføje @EnableConfigurationProperties (ConfigProperties.class) i den primære Spring-applikationsklasse for at binde egenskaberne til POJO:

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

Det er det! Spring binder automatisk enhver ejendom, der er defineret i vores ejendomsfil, der har præfikset post og det samme navn som et af felterne i ConfigProperties klasse.

Spring bruger nogle afslappede regler for bindende egenskaber. Som et resultat er følgende variationer alle bundet til ejendommen værtsnavn:

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

Derfor kan vi bruge følgende egenskabsfil til at indstille alle felterne:

#Simple egenskaber [e-mailbeskyttet] mail.port = 9000 [e-mailbeskyttet] 

3.1. Spring Boot 2.2

Fra og med Spring Boot 2.2 finder og registrerer Spring @ConfigurationProperties klasser via klassesti-scanning. Derfor, der er ikke behov for at kommentere sådanne klasser med @Komponent (og andre meta-annoteringer som @Configuration),eller endda bruge @EnableConfigurationProperties:

@ConfigurationProperties (prefix = "mail") offentlig klasse ConfigProperties {private String hostName; privat int port; privat streng fra; // standard getters og setter} 

Klassesti scanneren aktiveret af @SpringBootApplication finder den ConfigProperties klasse, selvom vi ikke kommenterede denne klasse med @Komponent.

Derudover kan vi bruge det @ConfigurationPropertiesScan kommentar for at scanne brugerdefinerede placeringer for konfigurationsejendomsklasser:

@SpringBootApplication @ConfigurationPropertiesScan ("com.baeldung.configurationproperties") public class EnableConfigurationDemoApplication {public static void main (String [] args) {SpringApplication.run (EnableConfigurationDemoApplication.class, args); }}

På denne måde vil Spring kun se efter konfigurationsejendomsklasser i com.baeldung.properties pakke.

4. Indlejrede egenskaber

Vi kan have indlejrede ejendomme i Lister, kort, og Klasser.

Lad os oprette et nyt Legitimationsoplysninger klasse til brug for nogle indlejrede egenskaber:

Public class Credentials {private String authMethod; privat streng brugernavn; privat strengadgangskode; // standard getters og setter}

Vi skal også opdatere ConfigProperties klasse til at bruge en Liste, -en Kort, og Legitimationsoplysninger klasse:

offentlig klasse ConfigProperties {privat streng vært; privat int port; privat streng fra; private List standardRecipients; privat kort yderligere overskrifter; private legitimationsoplysninger // standard getters og setter}

Følgende egenskabsfil indstiller alle felter:

#Simple egenskaber [e-mailbeskyttet] mail.port = 9000 [e-mailbeskyttet] #Listeegenskaber mail.defaultRecipients [0] [email protected] mail.defaultRecipients [1] [email protected] #Map Properties mail.additionalHeaders.redelivery = true mail .additionalHeaders.secure = sand # egenskaber for objekt mail.credentials.username = john mail.credentials.password = adgangskode mail.credentials.authMethod = SHA1

5. Brug @ConfigurationProperties på en @Bønne Metode

Vi kan også bruge @ConfigurationProperties kommentar til @Bønne-anmeldte metoder.

Denne tilgang kan være særlig nyttig, når vi vil binde egenskaber til en tredjepartskomponent, der er uden for vores kontrol.

Lad os oprette en simpel Vare klasse, som vi bruger i det næste eksempel:

public class Item {private String name; privat int størrelse // standard getters og setter}

Lad os nu se, hvordan vi kan bruge @ConfigurationProperties på en @Bønne metode til at binde eksternaliserede egenskaber til Vare eksempel:

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

Derfor vil en hvilken som helst elementpræfikset ejendom blive kortlagt til Vare instans styret af forårssammenhæng.

6. Validering af ejendom

@ConfigurationProperties giver validering af egenskaber ved hjælp af JSR-303-formatet. Dette tillader alle mulige pæne ting.

Lad os for eksempel lave værtsnavn ejendom obligatorisk:

@NotBlank privat strengværtsnavn;

Lad os derefter lave godkendelsesmetode ejendom fra 1 til 4 tegn:

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

Derefter Havn ejendom fra 1025 til 65536:

@Min (1025) @Max (65536) privat int-port; 

Endelig blev fra ejendommen skal matche et e-mail-adresseformat:

@Pattern (regexp = "^ [a-z0-9 ._% + -] [e-mail-beskyttet] [a-z0-9 .-] + \. [Az] {2,6} $") privat streng fra ; 

Dette hjælper os med at reducere en masse hvis ellers betingelser i vores kode, og får den til at se meget renere og mere kortfattet ud.

Hvis nogen af ​​disse valideringer mislykkes, starter hovedapplikationen ikke med et IllegalStateException.

Hibernate Validation-rammen bruger standard Java bønne-getters og settere, så det er vigtigt, at vi erklærer getters og setters for hver af egenskaberne.

7. Konvertering af ejendom

@ConfigurationProperties understøtter konvertering for flere typer af binding af egenskaberne til deres tilsvarende bønner.

7.1. Varighed

Vi starter med at se på konvertering af ejendomme til Varighed genstande.

Her har vi to felter af typen Varighed:

@ConfigurationProperties (præfiks = "konvertering") offentlig klasse PropertyConversion {privat Varighed timeInDefaultUnit; privat varighedstidInNano; ...}

Dette er vores egenskabsfil:

conversion.timeInDefaultUnit = 10 conversion.timeInNano = 9ns

Som et resultat, marken timeInDefaultUnit vil have en værdi på 10 millisekunder, og timeInNano har en værdi på 9 nanosekunder.

De understøttede enheder er ns, us, ms, s, m, h og d for henholdsvis nanosekunder, mikrosekunder, millisekunder, sekunder, minutter, timer og dage.

Standardenheden er millisekunder, hvilket betyder, at hvis vi ikke angiver en enhed ud for den numeriske værdi, konverterer Spring værdien til millisekunder.

Vi kan også tilsidesætte standardenheden ved hjælp af @DurationUnit:

@DurationUnit (ChronoUnit.DAYS) privat Varighed timeInDays;

Dette er den tilsvarende egenskab:

conversion.timeInDays = 2

7.2. DataSize

Tilsvarende Spring Boot @ConfigurationProperties bakker op DataSize type konvertering.

Lad os tilføje tre felter af typen DataSize:

privat DataSize størrelseInDefaultUnit; privat DataSize størrelseInGB; @DataSizeUnit (DataUnit.TERABYTES) privat DataSize størrelseInTB;

Dette er de tilsvarende egenskaber:

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

I dette tilfælde er sizeInDefaultUnit værdien er 300 byte, da standardenheden er byte.

De understøttede enheder er B, KB, MB, GBog TB. Vi kan også tilsidesætte standardenheden ved hjælp af @DataSizeUnit.

7.3. Brugerdefinerede Konverter

Vi kan også tilføje vores egen skik Konverter for at understøtte konvertering af en ejendom til en bestemt klassetype.

Lad os tilføje en simpel klasse Medarbejder:

offentlig klassemedarbejder {privat strengnavn; privat dobbelt løn }

Derefter opretter vi en brugerdefineret konverter til at konvertere denne egenskab:

konvertering. medarbejder = john, 2000

Vi konverterer det til en filtype Medarbejder:

privat ansat;

Vi bliver nødt til at gennemføre Konverter interface, derefter brug @ConfigurationPropertiesBinding kommentar for at registrere vores brugerdefinerede Konverter:

@Component @ConfigurationPropertiesBinding offentlig klasse EmployeeConverter implementerer Converter {@Override public Employee convert (String from) {String [] data = from.split (","); returnere ny medarbejder (data [0], Double.parseDouble (data [1])); }}

8. Uforanderlig @ConfigurationProperties Bindende

Fra og med Spring Boot 2.2, vi kan bruge @ConstructorBinding kommentar for at binde vores konfigurationsegenskaber.

Dette betyder i det væsentlige det @ConfigurationProperties-anmeldte klasser kan nu være uforanderlige.

@ConfigurationProperties (prefix = "mail.credentials") @ConstructorBinding public class ImmutableCredentials {private final String authMethod; privat endelig streng brugernavn; privat endelig strengadgangskode; public ImmutableCredentials (String authMethod, String username, String password) {this.authMethod = authMethod; this.username = brugernavn; this.password = adgangskode; } offentlig String getAuthMethod () {return authMethod; } public String getUsername () {return username; } public String getPassword () {return password; }}

Som vi kan se, når du bruger @ConstructorBinding, vi er nødt til at give konstruktøren alle de parametre, vi gerne vil binde.

Bemærk, at alle felter i ImmutableCredentials er endelige. Der er heller ikke nogen settermetoder.

Desuden er det vigtigt at understrege det for at bruge konstruktorbinding skal vi eksplicit aktivere vores konfigurationsklasse enten med @EnableConfigurationProperties eller med @ConfigurationPropertiesScan .

9. Konklusion

I denne artikel undersøgte vi @ConfigurationProperties annotering og fremhævet nogle af de nyttige funktioner, den giver, som afslappet binding og Bean Validation.

Som sædvanlig er koden tilgængelig på Github.