Gids voor @ConfigurationProperties in Spring Boot

1. Inleiding

Spring Boot heeft veel handige functies, waaronder externe configuratie en gemakkelijke toegang tot eigenschappen die zijn gedefinieerd in eigenschappenbestanden. In een eerdere tutorial zijn verschillende manieren beschreven waarop dit kan worden gedaan.

We gaan nu het @ConfigurationProperties annotatie in meer detail.

2. Installatie

Deze tutorial maakt gebruik van een vrij standaard setup. We beginnen met toevoegen spring-boot-starter-parent als de ouder in ons pom.xml:

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

Om eigenschappen die in het bestand zijn gedefinieerd te kunnen valideren, hebben we ook een implementatie van JSR-303 nodig, en slaapstand-validator is een van hen.

Laten we het toevoegen aan ons pom.xml ook:

 org.hibernate hibernate-validator 6.0.16.Final 

De pagina "Aan de slag met Hibernate Validator" bevat meer details.

3. Eenvoudige eigenschappen

De officiële documentatie adviseert dat we configuratie-eigenschappen isoleren in afzonderlijke POJO's.

Laten we daarmee beginnen:

@Configuration @ConfigurationProperties (prefix = "mail") openbare klasse ConfigProperties {privé String hostnaam; privé int poort; private String van; // standaard getters en setters}

We gebruiken @Configuratie zodat Spring een Spring bean creëert in de toepassingscontext.

@ConfigurationProperties werkt het beste met hiërarchische eigenschappen die allemaal hetzelfde voorvoegsel hebben; daarom voegen we een voorvoegsel toe van mail.

Het Spring-framework gebruikt standaard Java-bean-setters, dus we moeten setters voor elk van de eigenschappen declareren.

Opmerking: als we niet gebruiken @Configuratie in de POJO, dan moeten we toevoegen @EnableConfigurationProperties (ConfigProperties.class) in de belangrijkste Spring-toepassingsklasse om de eigenschappen in de POJO te binden:

@SpringBootApplication @EnableConfigurationProperties (ConfigProperties.class) openbare klasse EnableConfigurationDemoApplication {openbare statische leegte hoofd (String [] args) {SpringApplication.run (EnableConfigurationDemoApplication.class, args); }}

Dat is het! Spring zal automatisch elke eigenschap binden die is gedefinieerd in ons eigenschappenbestand met het voorvoegsel mail en dezelfde naam als een van de velden in het ConfigProperties klasse.

De lente gebruikt enkele ontspannen regels voor het binden van eigenschappen. Als gevolg hiervan zijn de volgende variaties allemaal gebonden aan het onroerend goed hostnaam:

mail.hostnaam mail.hostnaam mail.hostnaam mail.hostnaam mail.HOST_NAME 

Daarom kunnen we het volgende eigenschappenbestand gebruiken om alle velden in te stellen:

# Eenvoudige eigenschappen [e-mail beveiligd] mail.port = 9000 [e-mail beveiligd] 

3.1. Spring Boot 2.2

Vanaf Spring Boot 2.2 vindt en registreert Spring @ConfigurationProperties klassen via classpath scanning. Daarom het is niet nodig om dergelijke klassen te annoteren met @Component (en andere meta-annotaties zoals @Configuration),of gebruik zelfs de @EnableConfigurationProperties:

@ConfigurationProperties (prefix = "mail") openbare klasse ConfigProperties {privé String hostnaam; privé int poort; private String van; // standaard getters en setters} 

De klassenpadscanner ingeschakeld door @SpringBootApplication vindt de ConfigProperties klasse, ook al hebben we deze klasse niet geannoteerd met @Component.

Daarnaast kunnen we gebruik maken van de @ConfigurationPropertiesScan annotatie om aangepaste locaties te scannen op klassen van configuratie-eigenschappen:

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

Op deze manier zoekt Spring alleen naar klassen van configuratie-eigenschappen in de com.baeldung.properties pakket.

4. Geneste eigenschappen

We kunnen geneste eigenschappen hebben in Lijsten, kaarten, en Klassen.

Laten we een nieuw maken Inloggegevens klasse om te gebruiken voor sommige geneste eigenschappen:

public class Credentials {private String authMethod; private String gebruikersnaam; privé String-wachtwoord; // standaard getters en setters}

We moeten ook het ConfigProperties klasse om een Lijst, een Kaart, en de Inloggegevens klasse:

openbare klasse ConfigProperties {privé String-host; privé int poort; private String van; privélijst defaultRecipients; privékaart extraHeaders; persoonlijke referenties referenties; // standaard getters en setters}

Het volgende eigenschappenbestand zal alle velden instellen:

# Eenvoudige eigenschappen [e-mail beschermd] mail.port = 9000 [e-mail beschermd] #Lijst eigenschappen mail.defaultRecipients [0] [e-mail beschermd] mail.defaultRecipients [1] [e-mail beveiligd] #Map Eigenschappen mail.additionalHeaders.redelivery = true mail .additionalHeaders.secure = true #Objecteigenschappen mail.credentials.username = john mail.credentials.password = wachtwoord mail.credentials.authMethod = SHA1

5. Met behulp van @ConfigurationProperties op een @Boon Methode

We kunnen ook de @ConfigurationProperties annotatie op @Boon-geannoteerde methoden.

Deze benadering kan met name handig zijn als we eigenschappen willen binden aan een onderdeel van een derde partij waarover we geen controle hebben.

Laten we een eenvoudig maken Item klasse die we in het volgende voorbeeld zullen gebruiken:

public class Item {private String naam; privé int grootte; // standaard getters en setters}

Laten we nu eens kijken hoe we @ConfigurationProperties op een @Boon methode om extern gemaakte eigenschappen te binden aan het Item voorbeeld:

@Configuration openbare klasse ConfigProperties {@Bean @ConfigurationProperties (prefix = "item") openbaar item item () {retourneer nieuw item (); }}

Bijgevolg wordt elke eigenschap met een itemvoorvoegsel toegewezen aan de Item instantie beheerd door de Spring-context.

6. Eigendomsvalidatie

@ConfigurationProperties biedt validatie van eigenschappen met behulp van het JSR-303-formaat. Hierdoor zijn er allerlei leuke dingen mogelijk.

Laten we bijvoorbeeld de hostnaam eigenschap verplicht:

@NotBlank private String hostnaam;

Laten we vervolgens de authMethod eigenschap van 1 tot 4 tekens lang:

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

Dan de haven eigendom van 1025 tot 65536:

@Min (1025) @Max (65536) privé int-poort; 

eindelijk, de van eigenschap moet overeenkomen met de indeling van een e-mailadres:

@Pattern (regexp = "^ [a-z0-9 ._% + -] [e-mail beveiligd] [a-z0-9 .-] + \. [Az] {2,6} $") privé string van ; 

Dit helpt ons veel te verminderen als - anders voorwaarden in onze code, en zorgt ervoor dat het er veel schoner en beknopter uitziet.

Als een van deze validaties mislukt, start de hoofdtoepassing niet met een IllegalStateException.

Het Hibernate Validation-framework gebruikt standaard Java-bean-getters en setters, dus het is belangrijk dat we getters en setters declareren voor elk van de eigenschappen.

7. Eigendomsconversie

@ConfigurationProperties ondersteunt conversie voor meerdere soorten binding van de eigenschappen aan hun overeenkomstige bonen.

7.1. Looptijd

We beginnen met het omzetten van eigendommen in Looptijd voorwerpen.

Hier hebben we twee typen velden Looptijd:

@ConfigurationProperties (prefix = "conversion") openbare klasse PropertyConversion {privé Duur timeInDefaultUnit; privé Duur timeInNano; ...}

Dit is ons eigenschappenbestand:

conversion.timeInDefaultUnit = 10 conversion.timeInNano = 9ns

Als gevolg hiervan is het veld timeInDefaultUnit heeft een waarde van 10 milliseconden, en timeInNano heeft een waarde van 9 nanoseconden.

De ondersteunde eenheden zijn ns, us, ms, s, m, h en d voor respectievelijk nanoseconden, microseconden, milliseconden, seconden, minuten, uren en dagen.

De standaardeenheid is milliseconden, wat betekent dat als we geen eenheid specificeren naast de numerieke waarde, Spring de waarde zal omzetten in milliseconden.

We kunnen de standaardeenheid ook overschrijven met @DurationUnit:

@DurationUnit (ChronoUnit.DAYS) privé Duur timeInDays;

Dit is de bijbehorende eigenschap:

conversion.timeInDays = 2

7.2. DataSize

Evenzo Spring Boot @ConfigurationProperties ondersteunt DataSize type conversie.

Laten we drie typen velden toevoegen DataSize:

privé DataSize sizeInDefaultUnit; privé DataSize sizeInGB; @DataSizeUnit (DataUnit.TERABYTES) privé DataSize sizeInTB;

Dit zijn de bijbehorende eigenschappen:

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

In dit geval is het sizeInDefaultUnit waarde is 300 bytes, aangezien de standaardeenheid bytes is.

De ondersteunde eenheden zijn B, KB, MB, GB, en TB. We kunnen de standaardeenheid ook overschrijven met @DataSizeUnit.

7.3. Op maat Converter

We kunnen ook onze eigen op maat toevoegen Converter om het converteren van een eigenschap naar een specifiek klassetype te ondersteunen.

Laten we een eenvoudige klasse toevoegen Werknemer:

openbare klasse Werknemer {privé Stringnaam; particulier dubbel salaris; }

Vervolgens maken we een aangepaste converter om deze eigenschap te converteren:

conversie. werknemer = john, 2000

We zullen het converteren naar een bestand van het type Werknemer:

particulier Medewerker werknemer;

We zullen het Converter interface, dan gebruik @ConfigurationPropertiesBinding annotatie om onze gewoonte te registreren Converter:

@Component @ConfigurationPropertiesBinding public class EmployeeConverter implementeert Converter {@Override public Employee convert (String from) {String [] data = from.split (","); retourneer nieuwe werknemer (data [0], Double.parseDouble (data [1])); }}

8. Onveranderlijk @ConfigurationProperties Verbindend

Vanaf Spring Boot 2.2, we kunnen de @ConstructorBinding annotatie om onze configuratie-eigenschappen te binden.

Dit betekent in wezen dat @ConfigurationProperties-geannoteerde klassen kunnen nu onveranderlijk zijn.

@ConfigurationProperties (prefix = "mail.credentials") @ConstructorBinding openbare klasse ImmutableCredentials {private final String authMethod; private final String gebruikersnaam; privé definitief String-wachtwoord; openbare ImmutableCredentials (String authMethod, String gebruikersnaam, String wachtwoord) {this.authMethod = authMethod; this.username = gebruikersnaam; this.password = wachtwoord; } public String getAuthMethod () {return authMethod; } public String getUsername () {terugkeer gebruikersnaam; } public String getPassword () {wachtwoord retourneren; }}

Zoals we kunnen zien, bij gebruik @ConstructorBinding, we moeten de constructor alle parameters geven die we willen binden.

Merk op dat alle velden van Onveranderlijke inloggegevens zijn definitief. Er zijn ook geen setter-methoden.

Bovendien is het belangrijk om dat te benadrukken om de constructor-binding te gebruiken, moeten we onze configuratieklasse expliciet inschakelen met @EnableConfigurationProperties of met @ConfigurationPropertiesScan .

9. Conclusie

In dit artikel hebben we de @ConfigurationProperties annotatie en benadrukte enkele van de handige functies die het biedt, zoals ontspannen binding en Bean-validatie.

Zoals gewoonlijk is de code beschikbaar op Github.