Ejendomme med fjeder og fjederstøvle

1. Oversigt

Denne tutorial vises hvordan man opsætter og bruger egenskaber i foråret via Java-konfiguration og @PropertySource.

Vi ser også, hvordan egenskaber fungerer i Spring Boot.

2. Registrer en egenskabsfil via annoteringer

Forår 3.1 introducerer også den nye @PropertySource kommentar som en praktisk mekanisme til at tilføje ejendomskilder til miljøet.

Vi kan bruge denne kommentar i forbindelse med @Konfiguration kommentar:

@Configuration @PropertySource ("classpath: foo.properties") offentlig klasse PropertiesWithJavaConfig {// ...}

En anden meget nyttig måde at registrere en ny egenskabsfil på er at bruge en pladsholder, som giver os mulighed for det Vælg den rigtige fil dynamisk ved kørsel:

@PropertySource ({"classpath: persistence - $ {envTarget: mysql} .properties"}) ...

2.1. Definition af flere ejendomsplaceringer

Det @PropertySource annotering kan gentages i henhold til Java 8-konventioner. Derfor, hvis vi bruger Java 8 eller højere, kan vi bruge denne kommentar til at definere flere ejendomsplaceringer:

@PropertySource ("classpath: foo.properties") @PropertySource ("classpath: bar.properties") offentlig klasse PropertiesWithJavaConfig {// ...}

Selvfølgelig, vi kan også bruge @PropertySources kommentar og angiv en matrix af @PropertySource. Dette fungerer i enhver understøttet Java-version, ikke kun i Java 8 eller højere:

@PropertySources ({@PropertySource ("classpath: foo.properties"), @PropertySource ("classpath: bar.properties")}) offentlig klasse PropertiesWithJavaConfig {// ...}

I begge tilfælde er det værd at bemærke, at i tilfælde af en kollision med et ejendomsnavn har den sidst læste kilde forrang.

3. Brug / injektion af egenskaber

Injicere en ejendom med @Værdi kommentar er ligetil:

@Value ("$ {jdbc.url}") privat streng jdbcUrl;

Vi kan også angive en standardværdi for ejendommen:

@Value ("$ {jdbc.url: aDefaultUrl}") privat streng jdbcUrl;

Den nye PropertySourcesPlaceholderConfigurer tilføjet i foråret 3.1 løse $ {...} pladsholdere inden for værdier for bøndefinitionsegenskaber og @Værdi kommentarer.

Endelig kan vi opnå værdien af ​​en ejendom ved hjælp af Miljø API:

@Autowired private Environment env; ... dataSource.setUrl (env.getProperty ("jdbc.url"));

4. Egenskaber med fjederstøvle

Før vi går ind i mere avancerede konfigurationsindstillinger for egenskaber, lad os bruge lidt tid på at se på den nye egenskabsunderstøttelse i Spring Boot.

Generelt sagt, denne nye support involverer mindre konfiguration sammenlignet med standard Spring, hvilket naturligvis er et af hovedmålene med Boot.

4.1. application.properties: standardegenskabsfilen

Boot anvender sin typiske konvention over konfigurationsmetode til ejendomsfiler. Det betyder at vi kan simpelthen sætte en application.properties fil i vores src / main / ressourcer bibliotek, og det registreres automatisk. Vi kan derefter indsprøjte alle indlæste egenskaber fra det som normalt.

Så ved at bruge denne standardfil behøver vi ikke eksplicit at registrere en PropertySource eller endda give en sti til en ejendomsfil.

Vi kan også konfigurere en anden fil ved kørsel, hvis vi har brug for det ved hjælp af en miljøegenskab:

java -jar app.jar --spring.config.location = classpath: /another-location.properties

Fra og med Spring Boot 2.3, Vi kan også specificere placeringer af jokertegn til konfigurationsfiler.

For eksempel kan vi indstille spring.config.location ejendom til config / * /:

java -jar app.jar --spring.config.location = config / * /

På denne måde vil Spring Boot se efter konfigurationsfiler, der matcher config / * / katalogmønster uden for vores jar-fil. Dette er praktisk, når vi har flere kilder til konfigurationsegenskaber.

Siden version 2.4.0, Spring Boot understøtter brug af egenskaber med flere dokumenter, ligesom YAML gør ved design:

baeldung.customProperty = defaultValue # --- baeldung.customProperty = overriddenValue

Bemærk, at for egenskabsfiler er noteringen med tre bindestreger foran en kommentar (#).

4.2. Miljøspecifikke egenskabsfiler

Hvis vi har brug for at målrette mod forskellige miljøer, er der en indbygget mekanisme til det i Boot.

Vi kan simpelthen definere en applikationsmiljø.egenskaber fil i src / main / ressourcer bibliotek, og indstil derefter en forårsprofil med det samme miljønavn.

For eksempel, hvis vi definerer et "iscenesættende" miljø, betyder det, at vi bliver nødt til at definere et iscenesættelse profil og derefter application-staging.properties.

Denne env-fil indlæses og har forrang over standardegenskabsfilen. Bemærk, at standardfilen stadig indlæses, det er bare, at når der er en ejendomskollision, har den miljøspecifikke ejendomsfil forrang.

4.3. Testspecifikke egenskabsfil

Vi har muligvis også et krav om at bruge forskellige egenskabsværdier, når vores applikation er under test.

Spring Boot håndterer dette for os ved at kigge i vores src / test / ressourcer katalog under en testkørsel. Igen vil standardegenskaber stadig kunne injiceres som normalt, men vil blive tilsidesat af disse, hvis der er en kollision.

4.4. Det @TestPropertySource Kommentar

Hvis vi har brug for mere detaljeret kontrol over testegenskaber, kan vi bruge @TestPropertySource kommentar.

Dette giver os mulighed for at indstille testegenskaber til en bestemt testkontekst med forrang over standardegenskabskilderne:

@RunWith (SpringRunner.class) @TestPropertySource ("/ foo.properties") offentlig klasse FilePropertyInjectionUnitTest {@Value ("$ {foo}") privat String foo; @Test offentligt ugyldigt nårFilePropertyProvided_thenProperlyInjected () {assertThat (foo) .isEqualTo ("bar"); }}

Hvis vi ikke vil bruge en fil, kan vi angive navne og værdier direkte:

@RunWith (SpringRunner.class) @TestPropertySource (egenskaber = {"foo = bar"}) offentlig klasse PropertyInjectionUnitTest {@Value ("$ {foo}") privat String foo; @Test offentligt ugyldigt nårPropertyProvided_thenProperlyInjected () {assertThat (foo) .isEqualTo ("bar"); }}

Vi kan også opnå en lignende effekt ved hjælp af ejendomme argument af @SpringBootTest kommentar:

@RunWith (SpringRunner.class) @SpringBootTest (egenskaber = {"foo = bar"}, klasser = SpringBootPropertiesTestApplication.class) offentlig klasse SpringBootPropertyInjectionIntegrationTest {@Value ("$ {foo}") privat String foo; @Test offentligt ugyldigt nårSpringBootPropertyProvided_thenProperlyInjected () {assertThat (foo) .isEqualTo ("bar"); }}

4.5. Hierarkiske egenskaber

Hvis vi har egenskaber, der er grupperet sammen, kan vi gøre brug af @ConfigurationProperties annotation, som kortlægger disse egenskabshierarkier i Java-objektegrafer.

Lad os tage nogle egenskaber, der bruges til at konfigurere en databaseforbindelse:

database.url = jdbc: postgresql: / localhost: 5432 / forekomst database.username = foo database.password = bar

Og så lad os bruge kommentaren til at kortlægge dem til et databaseobjekt:

@ConfigurationProperties (prefix = "database") offentlig klasse database {String url; String brugernavn; Strengadgangskode; // standard getters og setter}

Spring Boot anvender sin konvention over konfigurationsmetode igen, automatisk kortlægning mellem ejendomsnavne og deres tilsvarende felter. Alt, hvad vi har brug for, er ejendomspræfikset.

Hvis du vil grave dybere i konfigurationsegenskaber, skal du se på vores dybtgående artikel.

4.6. Alternativ: YAML-filer

Spring understøtter også YAML-filer.

Alle de samme navngivningsregler gælder for testspecifikke, miljøspecifikke og standardegenskabsfiler. Den eneste forskel er filtypen og en afhængighed af, at SnakeYAML-biblioteket er på vores klassesti.

YAML er især god til hierarkisk ejendomsopbevaring; følgende egenskabsfil:

database.url = jdbc: postgresql: / localhost: 5432 / forekomst database.username = foo database.password = bjælkehemmelighed: foo

er synonymt med følgende YAML-fil:

database: url: jdbc: postgresql: / localhost: 5432 / instans brugernavn: foo adgangskode: barhemmelighed: foo

Det er også værd at nævne, at YAML-filer ikke understøtter @PropertySource kommentar, så hvis vi har brug for denne kommentar, vil det begrænse os til at bruge en egenskabsfil.

Et andet bemærkelsesværdigt punkt er, at Spring Boot i version 2.4.0 ændrede den måde, hvorpå egenskaber indlæses fra YAML-filer med flere dokumenter. Tidligere var rækkefølgen, som de blev tilføjet, baseret på profilaktiveringsrækkefølgen. Med den nye version følger rammen dog de samme ordreregler, som vi tidligere angav for .ejendomme filer; egenskaber, der er erklæret lavere i filen, tilsidesætter simpelthen de højere op.

Derudover kan profiler i denne version ikke længere aktiveres fra profilspecifikke dokumenter, hvilket gør resultatet klarere og mere forudsigeligt.

4.7. Import af yderligere konfigurationsfiler

Før version 2.4.0 tillod Spring Boot at inkludere yderligere konfigurationsfiler ved hjælp af spring.config.location og spring.config.additional-location egenskaber, men de havde visse begrænsninger. For eksempel skulle de defineres, før applikationen startede (som miljø- eller systemegenskaber eller ved hjælp af kommandolinjeargumenter), da de blev brugt tidligt i processen.

I den nævnte version, vi kan bruge spring.config.import ejendom inden for application.properties eller ansøgning.yml fil for nemt at inkludere yderligere filer. Denne ejendom understøtter nogle interessante funktioner:

  • tilføje flere filer eller mapper
  • filerne kan indlæses enten fra klassestien eller fra en ekstern bibliotek
  • angiver, om startprocessen mislykkes, hvis en fil ikke findes, eller om det er en valgfri fil
  • importerer filer uden filendelse

Lad os se et gyldigt eksempel:

spring.config.import = classpath: additional-application.properties, classpath: additional-application [.yml], optional: file: ./ external.properties, classpath: additional-application-properties /

Bemærk: her har vi formateret denne egenskab ved hjælp af linjeskift bare for klarhedens skyld.

Spring behandler import som et nyt dokument indsat umiddelbart under importdeklarationen.

4.8. Egenskaber fra kommandolinjeargumenter

Udover at bruge filer kan vi videregive egenskaber direkte på kommandolinjen:

java -jar app.jar --property = "værdi"

Vi kan også gøre dette via systemegenskaber, som leveres før -krukke kommando snarere end efter det:

java -Dproperty.name = "værdi" -jar app.jar

4.9. Egenskaber fra miljøvariabler

Spring Boot vil også opdage miljøvariabler og behandle dem som egenskaber:

eksportnavn = værdi java -jar app.jar 

4.10. Randomisering af ejendomsværdier

Hvis vi ikke ønsker deterministiske egenskabsværdier, kan vi bruge RandomValuePropertySource for at randomisere værdierne for egenskaber:

random.number = $ {random.int} random.long = $ {random.long} random.uuid = $ {random.uuid}

4.11. Yderligere typer ejendomskilder

Spring Boot understøtter en lang række ejendomskilder og implementerer en gennemtænkt ordre for at muliggøre fornuftig tilsidesættelse. Det er værd at konsultere den officielle dokumentation, som går længere end omfanget af denne artikel.

5. Konfiguration ved hjælp af rå bønner - den PropertySourcesPlaceholderConfigurer

Udover de praktiske metoder til at få egenskaber ind i Spring, kan vi også definere og omregistrere egenskabskonfigurationsbønnen manuelt.

Arbejde med PropertySourcesPlaceholderConfigurer giver os fuld kontrol over konfigurationen, med ulempen ved at være mere detaljeret og det meste af tiden unødvendig.

Lad os se, hvordan vi kan definere denne bønne ved hjælp af Java-konfiguration:

@Bean offentlig statisk PropertySourcesPlaceholderConfigurer egenskaber () {PropertySourcesPlaceholderConfigurer pspc = ny PropertySourcesPlaceholderConfigurer (); Ressource [] ressourcer = ny ClassPathResource [] {ny ClassPathResource ("foo.properties")}; pspc.setLocations (ressourcer); pspc.setIgnoreUnresolvablePlaceholders (true); retur pspc; }

6. Egenskaber i forældre-barn-sammenhænge

Dette spørgsmål kommer op igen og igen: Hvad sker der, når vores webapplikation har en forælder og en barnekontekst? Forældrekonteksten kan have nogle almindelige kernefunktionaliteter og bønner og derefter en (eller flere) barnekontekster, måske indeholdende servlet-specifikke bønner.

I så fald, hvad er den bedste måde at definere egenskabsfiler og inkludere dem i disse sammenhænge? Og hvordan kan man bedst hente disse egenskaber fra foråret?

Vi giver en simpel opdeling.

Hvis filen er defineret i overordnet sammenhæng:

  • @Værdi arbejder i Børnekontekst: JA
  • @Værdi arbejder i Forældrekontekst: JA
  • environment.getProperty i Børnekontekst: JA
  • environment.getProperty i Forældrekontekst: JA

Hvis filen er defineret i barnekonteksten:

  • @Værdi arbejder i Børnekontekst: JA
  • @Værdi arbejder i Forældrekontekst: NEJ
  • environment.getProperty i Børnekontekst: JA
  • environment.getProperty i Forældrekontekst: NEJ

7. Konklusion

Denne artikel viste flere eksempler på arbejde med egenskaber og egenskabsfiler i foråret.

Som altid er hele koden, der understøtter artiklen, tilgængelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found