Ponovno učitavanje datoteka svojstava u proljeće

1. Pregled

U ovom uputstvu ćemo pokazati kako ponovno učitati svojstva u Spring aplikaciji.

2. Čitanje svojstava u proljeće

Na proljeće imamo različite mogućnosti za pristup svojstvima:

  1. Okoliš - Možemo ubrizgati Okoliš a zatim upotrijebite Okoliš # getProperty čitati dano svojstvo. Okoliš sadrži različite izvore svojstava poput svojstava sustava, -D parametri i application.properties (.yml). Također, dodatni izvori imovine mogu se dodati u Okoliš koristeći @PropertySource.
  2. Svojstva - Možemo učitati datoteke svojstava u Svojstva primjerice, zatim ga upotrijebite u grahu pozivanjem svojstva.get ("svojstvo").
  3. @Vrijednost - Sa grahom možemo ubrizgati određeno svojstvo u zrnu @Vrijednost ($ {‘svojstvo’}) bilješka.
  4. @ConfigurationProperties - možemo koristiti @ConfigurationProperties za učitavanje hijerarhijskih svojstava u grah.

3. Ponovno učitavanje svojstava iz vanjske datoteke

Da bismo tijekom izvođenja promijenili svojstva u datoteci, trebali bismo je smjestiti negdje izvan staklenke. Zatim ćemo naredbenom retku reći Springu gdje jeparametar –Spring.config.location = datoteka: // {put do datoteke}. Ili ga možemo staviti primjena.svojstva.

U svojstvima koja se temelje na datotekama, morat ćemo odabrati način za ponovno učitavanje datoteke. Na primjer, možemo razviti krajnju točku ili planer za čitanje datoteke i ažuriranje svojstava.

Jedna zgodna knjižnica za ponovno učitavanje datoteke je Apacheova zajednička-konfiguracija. Možemo koristiti PropertiesConfiguration s različitim ReloadingStrategy.

Dodajmo zajednička-konfiguracija našem pom.xml:

 commons-configuration zajednička-konfiguracija 1.10 

Zatim dodamo metodu za stvaranje a PropertiesConfiguration grah, koji ćemo koristiti kasnije:

@Bean @ConditionalOnProperty (name = "spring.config.location", matchIfMissing = false) public PropertiesConfiguration propertiesConfiguration (@Value ("$ {spring.config.location}") String path) baca izuzetak {String filePath = new File (path .substring ("datoteka:". length ())). getCanonicalPath (); PropertiesConfiguration configuration = nova PropertiesConfiguration (nova datoteka (filePath)); configuration.setReloadingStrategy (novi FileChangedReloadingStrategy ()); povratna konfiguracija; }

U gornjem kodu smo postavili FileChangedReloadingStrategy kao strategija ponovnog učitavanja sa zadanim kašnjenjem osvježavanja. Ovo znači to PropertiesConfiguration provjerava datum izmjene datoteke ako je njegova posljednja provjera bila prije 5000ms.

Odgodu možemo prilagoditi pomoću FileChangedReloadingStrategy # setRefreshDelay.

3.1. Pretovar Okoliš Svojstva

Ako želimo ponovno učitati svojstva učitana kroz Okoliš primjerice, moramo produžiti PropertySource a zatim upotrijebite PropertiesConfiguration za vraćanje novih vrijednosti iz vanjske datoteke svojstava.

Počnimo s proširivanjem PropertySource:

javna klasa ReloadablePropertySource proširuje PropertySource {PropertiesConfiguration propertiesConfiguration; javni ReloadablePropertySource (naziv niza, PropertiesConfiguration propertiesConfiguration) {super (ime); this.propertiesConfiguration = svojstvaConfiguration; } javni ReloadablePropertySource (naziv niza, put niza) {super (StringUtils.hasText (ime)? put: ime); isprobajte {this.propertiesConfiguration = new PropertiesConfiguration (put); this.propertiesConfiguration.setReloadingStrategy (novi FileChangedReloadingStrategy ()); } catch (Exception e) {throw new PropertiesException (e); }} @Override javni objekt getProperty (Nizovi) {return svojstvaConfiguration.getProperty (s); }}

Nadjačali smo getProperty metoda za njegovo delegiranje PropertiesConfiguration # getProperty. Stoga će provjeravati ažurirane vrijednosti u intervalima prema našem kašnjenju osvježavanja.

Sada ćemo dodati svoje ReloadablePropertySource do OkolišIzvori imovine:

@Configuration javna klasa ReloadablePropertySourceConfig {private ConfigurableEnvironment env; javni ReloadablePropertySourceConfig (@Autowired ConfigurableEnvironment env) {this.env = env; } @Bean @ConditionalOnProperty (name = "spring.config.location", matchIfMissing = false) public ReloadablePropertySource reloadablePropertySource (PropertiesConfiguration properties) {ReloadablePropertySource ret = new ReloadablePropertySource ("dynamic", properties); Izvori MutablePropertySources = env.getPropertySources (); sources.addFirst (ret); povratak ret; }}

Kao prvu stavku dodali smo novi izvor svojstva jer želimo da istim ključem nadjača bilo koje postojeće svojstvo.

Stvorimo grah za čitanje svojstva Okoliš:

@Component javna klasa EnvironmentConfigBean {privatno okruženje okoliša; public EnvironmentConfigBean (@Autowired Environment Environment) {this.environment = okolina; } javni String getColor () {return environment.getProperty ("application.theme.color"); }}

Ako trebamo dodati druge vanjske izvore svojstava koja se mogu ponovno učitati, prvo moramo implementirati svoj običaj PropertySourceFactory:

javna klasa ReloadablePropertySourceFactory proširuje DefaultPropertySourceFactory {@Override javni PropertySource createPropertySource (String s, EncodedResource encodedResource) baca IOException {Resource internal = encodedResource.getResource (); ako (interna instanca FileSystemResource) vrati novi ReloadablePropertySource (s, ((FileSystemResource) interni) .getPath ()); ako (interna instanca FileUrlResource) vrati novi ReloadablePropertySource (s, ((FileUrlResource) interni) .getURL () .getPath ()); vrati super.createPropertySource (s, encodedResource); }}

Tada možemo označiti klasu komponente s @PropertySource:

@PropertySource (value = "datoteka: put-do-konfiguracije", tvornica = ReloadablePropertySourceFactory.class)

3.2. Ponovno učitavanje instance svojstava

Okoliš je bolji izbor od Svojstva, pogotovo kada moramo ponovno učitati svojstva iz datoteke. Međutim, ako nam zatreba, možemo produžiti java.util.Vlasnosti:

javna klasa ReloadableProperties proširuje svojstva {private PropertiesConfiguration propertiesConfiguration; public ReloadableProperties (PropertiesConfiguration propertiesConfiguration) baca IOException {super.load (novi FileReader (propertiesConfiguration.getFile ())); this.propertiesConfiguration = svojstvaConfiguration; } @Override javni String getProperty (ključ niza) {String val = propertiesConfiguration.getString (ključ); super.setProperty (ključ, val); povratni val; } // ostale nadjačavanja}

Nadjačali smo getProperty i njegova preopterećenja, a zatim ga je dodijelio a PropertiesConfiguration primjer. Sada možemo stvoriti zrno graha ove klase i ubrizgati ga u svoje komponente.

3.3. Ponovno učitavanje Beana sa @ConfigurationProperties

Da biste postigli isti efekt s @ConfigurationProperties, trebali bismo rekonstruirati instancu.

Ali, Spring će samo stvoriti novu instancu komponenata pomoću prototip ili zahtjev opseg.

Dakle, naša tehnika za ponovno učitavanje okoline također će raditi za njih, ali za jednotočke nemamo drugog izbora osim implementacije krajnje točke za uništavanje i ponovno stvaranje graha ili za rukovanje ponovnim učitavanjem svojstva unutar samog graha.

3.4. Ponovno učitavanje Beana sa @Vrijednost

The @Vrijednost napomena predstavlja ista ograničenja kao i @ConfigurationProperties.

4. Ponovno učitavanje svojstava pomoću aktuatora i oblaka

Spring Actuator pruža različite krajnje točke za zdravlje, mjerne podatke i konfiguracije, ali ništa za osvježavanje graha. Dakle, trebamo Spring Cloud da dodamo a /osvježiti krajnja točka za to. Ova krajnja točka ponovno učitava sve izvore svojstva Okoliš a zatim objavljuje EnvironmentChangeEvent.

Spring Cloud je također predstavio @RefreshScope, a možemo ga koristiti za klase konfiguracije ili grah. Kao rezultat, zadani opseg bit će osvježiti umjesto jednokrevetna.

Koristeći osvježiti opsega, Spring će očistiti svoju unutarnju predmemoriju tih komponenata na EnvironmentChangeEvent. Zatim se pri sljedećem pristupu grahu stvara nova instanca.

Krenimo dodavanjem pokretač pokretača opruge-čizme našem pom.xml:

 org.springframework.boot opruga-pokretač-pokretač-pokretač 

Zatim, neka je i uvoz ovisnosti proljeća-oblaka:

   org.springframework.cloud proljeće-oblak-ovisnosti $ {spring-cloud.version} pom uvoz Greenwich.SR1 

A onda dodamo proljeće-oblak-starter:

 org.springframework.cloud proljeće-oblak-starter 

Na kraju, omogućimo krajnju točku osvježavanja:

management.endpoints.web.exposure.include = osvježi

Kada koristimo Spring Cloud, možemo postaviti Config Server za upravljanje svojstvima, ali također možemo nastaviti s vanjskim datotekama. Sada se možemo nositi s dvije druge metode čitanja svojstava: @Vrijednost i @ConfigurationProperties.

4.1. Osvježite grah s @ConfigurationProperties

Pokažimo kako se koristi @ConfigurationProperties s @RefreshScope:

@Component @ConfigurationProperties (prefix = "application.theme") @RefreshScope javna klasa ConfigurationPropertiesRefreshConfigBean {boja privatnog niza; javna praznina setColor (boja niza) {this.color = color; } // getter i ostale stvari}

Naš grah čita „boja" svojstvo iz korijena “Prijava.tema" imovine. Imajte na umu da nam treba metoda postavljanja, prema Springovoj dokumentaciji.

Nakon što promijenimo vrijednost "aplikacija.tema.boja”U našoj vanjskoj konfiguracijskoj datoteci, možemo nazvati /osvježiti, tako da novu vrijednost možemo dobiti iz graha pri sljedećem pristupu.

4.2. Osvježite grah s @Vrijednost

Stvorimo našu komponentu uzorka:

@Component @RefreshScope javna klasa ValueRefreshConfigBean {private String color; public ValueRefreshConfigBean (@Value ("$ {application.theme.color}") Boja niza) {this.color = color; } // ovdje stavi getter}

Postupak osvježavanja isti je kao i gore.

Međutim, potrebno je napomenuti da /osvježiti neće raditi za grah s eksplicitnim jednokrevetna opseg.

5. Zaključak

U ovom uputstvu pokazali smo kako ponovno učitati svojstva sa ili bez značajki Spring Cloud. Također, pokazali smo zamke i iznimke svake od tehnika.

Kompletni kod dostupan je u našem GitHub projektu.