Last inn eiendomsfiler på nytt om våren

1. Oversikt

I denne opplæringen skal vi vise hvordan du kan laste inn egenskaper i en vårapplikasjon.

2. Leseegenskaper om våren

Vi har forskjellige alternativer for å få tilgang til eiendommer våren:

  1. Miljø - Vi kan injisere Miljø og bruk deretter Miljø # getProperty å lese en gitt eiendom. Miljø inneholder forskjellige eiendomskilder som systemegenskaper, -D parametere, og application.properties (.yml). Ekstra eiendomskilder kan også legges til i Miljø ved hjelp av @PropertySource.
  2. Eiendommer - Vi kan laste inn eiendomsfiler i en Eiendommer for eksempel, bruk den i en bønne ved å ringe eiendommer.get (“eiendom”).
  3. @Verdi - Vi kan injisere en bestemt egenskap i en bønne med @Value ($ {‘eiendom '}) kommentar.
  4. @ConfigurationProperties - Vi kan bruke @ConfigurationProperties for å laste hierarkiske egenskaper i en bønne.

3. Laste inn egenskaper fra ekstern fil

For å endre egenskaper i en fil i løpet av kjøretiden, bør vi plassere den filen et sted utenfor glasset. Deretter vil vi fortelle våren hvor det er med kommandolinjenparameter –Spring.config.location = file: // {path to file}. Eller vi kan sette den inn application.properties.

I filbaserte egenskaper må vi velge en måte å laste inn filen på nytt. For eksempel kan vi utvikle et sluttpunkt eller en planlegger for å lese filen og oppdatere egenskapene.

Et praktisk bibliotek for å laste inn filen på nytt er Apache's commons-konfigurasjon. Vi kan bruke Egenskaper Konfigurasjon med forskjellige Last på nytt Strategi.

La oss legge til commons-konfigurasjon til vår pom.xml:

 commons-configuration commons-configuration 1.10 

Deretter legger vi til en metode for å lage en Egenskaper Konfigurasjon bønne, som vi bruker senere:

@Bean @ConditionalOnProperty (navn = "spring.config.location", matchIfMissing = false) offentlige PropertiesConfiguration egenskaperConfiguration (@Value ("$ {spring.config.location}") strengbane) kaster unntak {String filePath = ny fil (bane .substring ("fil:". lengde ())). getCanonicalPath (); PropertiesConfiguration configuration = new PropertiesConfiguration (new File (filePath)); configuration.setReloadingStrategy (ny FileChangedReloadingStrategy ()); retur konfigurasjon; }

I koden ovenfor har vi satt FileChangedReloadingStrategy som omlastingsstrategi med standard oppdateringsforsinkelse. Dette betyr at Egenskaper Konfigurasjon sjekker for filendringsdatoen hvis den siste sjekken var før 5000 ms siden.

Vi kan tilpasse forsinkelsen ved hjelp av FileChangedReloadingStrategy # setRefreshDelay.

3.1. Laster om Miljø Eiendommer

Hvis vi vil laste inn egenskapene som er lastet gjennom en Miljø for eksempel må vi utvide PropertySource og bruk deretter Egenskaper Konfigurasjon for å returnere nye verdier fra den eksterne eiendomsfilen.

La oss starte med å utvide PropertySource:

offentlig klasse ReloadablePropertySource utvider PropertySource {PropertiesConfiguration propertiesConfiguration; public ReloadablePropertySource (strengnavn, PropertiesConfiguration egenskaperConfiguration) {super (navn); this.propertiesConfiguration = egenskaperConfiguration; } offentlig ReloadablePropertySource (strengnavn, strengbane) {super (StringUtils.hasText (navn)? bane: navn); prøv {this.propertiesConfiguration = nye PropertiesConfiguration (sti); this.propertiesConfiguration.setReloadingStrategy (ny FileChangedReloadingStrategy ()); } fange (Unntak e) {kaste nye PropertiesException (e); }} @ Override public Object getProperty (String s) {return propertiesConfiguration.getProperty (s); }}

Vi har overstyrt getProperty metode for å delegere den til PropertiesConfiguration # getProperty. Derfor vil den se etter oppdaterte verdier i intervaller i henhold til vår oppdateringsforsinkelse.

Nå skal vi legge til vår ReloadablePropertySource til Miljø’S eiendomskilder:

@Configuration public class ReloadablePropertySourceConfig {private ConfigurableEnvironment env; public ReloadablePropertySourceConfig (@Autowired ConfigurableEnvironment env) {this.env = env; } @Bean @ConditionalOnProperty (navn = "spring.config.location", matchIfMissing = false) offentlig ReloadablePropertySource reloadablePropertySource (PropertiesConfiguration egenskaper) {ReloadablePropertySource ret = ny ReloadablePropertySource ("dynamisk", egenskaper); MutablePropertySources sources = env.getPropertySources (); sources.addFirst (ret); retur ret; }}

Vi har lagt til den nye eiendomskilden som det første elementet fordi vi vil at den skal overstyre eksisterende eiendommer med samme nøkkel.

La oss lage en bønne å lese en eiendom fra Miljø:

@Component offentlig klasse EnvironmentConfigBean {private Environment miljø; public EnvironmentConfigBean (@Autowired Environment environment) {this.environment = miljø; } public String getColor () {return environment.getProperty ("application.theme.color"); }}

Hvis vi trenger å legge til andre kilder som kan lastes på eksterne egenskaper, må vi først implementere vår tilpassede PropertySourceFactory:

offentlig klasse ReloadablePropertySourceFactory utvider DefaultPropertySourceFactory {@Override public PropertySource createPropertySource (String s, EncodedResource encodedResource) kaster IOException {Ressurs intern = encodedResource.getResource (); hvis (intern forekomst av FileSystemResource) returnerer ny ReloadablePropertySource (s, ((FileSystemResource) intern) .getPath ()); hvis (intern forekomst av FileUrlResource) returnerer ny ReloadablePropertySource (s, ((FileUrlResource) intern) .getURL () .getPath ()); returner super.createPropertySource (s, encodedResource); }}

Da kan vi kommentere klassen til en komponent med @PropertySource:

@PropertySource (value = "file: path-to-config", fabrikk = ReloadablePropertySourceFactory.class)

3.2. Laster inn eiendomsforekomst

Miljø er et bedre valg enn Eiendommer, spesielt når vi trenger å laste inn egenskaper fra en fil på nytt. Men hvis vi trenger det, kan vi utvide java.util.Eiendommer:

offentlig klasse ReloadableProperties utvider Properties {private PropertiesConfiguration propertiesConfiguration; public ReloadableProperties (PropertiesConfiguration propertiesConfiguration) kaster IOException {super.load (ny FileReader (propertiesConfiguration.getFile ())); this.propertiesConfiguration = egenskaperConfiguration; } @ Override public String getProperty (strengnøkkel) {String val = propertiesConfiguration.getString (key); super.setProperty (nøkkel, val); retur val; } // andre overstyringer}

Vi har overstyrt getProperty og dens overbelastning, delegerte den deretter til a Egenskaper Konfigurasjon forekomst. Nå kan vi lage en bønne av denne klassen og injisere den i komponentene våre.

3.3. Laster om Bean med @ConfigurationProperties

For å få samme effekt med @ConfigurationProperties, vi trenger å rekonstruere forekomsten.

Men Spring vil bare opprette en ny forekomst av komponenter med prototype eller be om omfang.

Dermed vil vår teknikk for å laste opp miljøet også fungere for dem, men for enkeltpersoner har vi ikke noe annet valg enn å implementere et endepunkt for å ødelegge og gjenskape bønnen, eller for å håndtere eiendomsopplastingen inne i selve bønnen.

3.4. Laster om Bean med @Verdi

De @Verdi merknader har de samme begrensningene som @ConfigurationProperties.

4. Laste inn egenskaper etter aktuator og sky

Spring Actuator gir forskjellige sluttpunkter for helse, beregninger og konfigurasjoner, men ingenting for forfriskende bønner. Dermed trenger vi Spring Cloud for å legge til en /forfriske endepunkt for det. Dette endepunktet laster alle egenskapskilder på Miljø og publiserer deretter en EnvironmentChangeEvent.

Spring Cloud har også introdusert @RefreshScope, og vi kan bruke den til konfigurasjonsklasser eller bønner. Som et resultat vil standardomfanget være forfriske i stedet for singleton.

Ved hjelp av forfriske omfang, vil Spring tømme den interne hurtigbufferen for disse komponentene på en EnvironmentChangeEvent. Deretter opprettes en ny forekomst ved neste tilgang til bønnen.

La oss starte med å legge til spring-boot-starter-actuator til vår pom.xml:

 org.springframework.boot spring-boot-starter-actuator 

La oss også importere vår-sky-avhengigheter:

   org.springframework.cloud spring-cloud-dependencies $ {spring-cloud.version} pom importerer Greenwich.SR1 

Og så legger vi til vår-sky-starter:

 org.springframework.cloud spring-cloud-starter 

Til slutt, la oss aktivere oppdateringspunktet:

management.endpoints.web.exposure.include = oppdater

Når vi bruker Spring Cloud, kan vi sette opp en Config Server for å administrere egenskapene, men vi kan også fortsette med våre eksterne filer. Nå kan vi håndtere to andre metoder for å lese egenskaper: @Verdi og @ConfigurationProperties.

4.1. Oppdater bønner med @ConfigurationProperties

La oss vise hvordan du bruker @ConfigurationProperties med @RefreshScope:

@Component @ConfigurationProperties (prefix = "application.theme") @RefreshScope offentlig klasse ConfigurationPropertiesRefreshConfigBean {private String farge; public void setColor (strengfarge) {this.color = color; } // getter og andre ting}

Bønnen vår leser “farge" eiendom fra roten "applikasjon.tema" eiendom. Merk at vi trenger settermetoden, i henhold til vårens dokumentasjon.

Etter at vi endrer verdien av “applikasjon.tema.farge”I vår eksterne konfigurasjonsfil kan vi ringe /forfriske, så da kan vi få den nye verdien fra bønnen ved neste tilgang.

4.2. Oppdater bønner med @Verdi

La oss lage vår prøvekomponent:

@Component @RefreshScope offentlig klasse ValueRefreshConfigBean {private String farge; offentlig ValueRefreshConfigBean (@Value ("$ {application.theme.color}") Strengfarge) {this.color = color; } // put getter her}

Oppfriskningsprosessen er den samme som ovenfor.

Det er imidlertid nødvendig å merke seg det /forfriske fungerer ikke for bønner med en eksplisitt singleton omfang.

5. Konklusjon

I denne opplæringen har vi demonstrert hvordan du kan laste inn egenskaper med eller uten Spring Cloud-funksjoner. Vi har også vist fallgruvene og unntakene fra hver av teknikkene.

Den komplette koden er tilgjengelig i vårt GitHub-prosjekt.


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