Ako injektovať do inštančných premenných beanov hodnoty z properties súborov? Ukážme si to na príklade dátumového servisu, ktorý vypíše aktuálny dátum vo formáte nakonfigurovanom v .properties
súbore.
Budeme potrebovať:
- jeden
.properties
súbor - jeden bean s inštančnou premennou, do ktorej budeme injektovať hodnoty
- jednu konfiguráciu aplikačného kontextu
- registráciu beanu pre
PropertySourcesPlaceholderConfigurer
- registráciu beanu pre
- jeden unit test
Súbor s .properties
V balíčku sk.upjs.ics.novotnyr.spring
vytvorme date.properties
. Ak bude v balíčku, budeme k nemu vedieť pristúpiť cez springácky ClassPathResource
:
date.format=yyyy-MM-dd
Bean s injektovanou inštančnou premennou
Jadro bude nasledovné:
public class DateService {
@Value("${date.format}")
private String format;
...
Hodnota do inštančnej premennej format
sa vloží za behu na základe .properties
súboru, a to podľa kľúča date.format
. Nezabudnime na dolárokučeravozátvorkový obal!
Injektáž prebehne pomocou springáckej anotácie @Value
.
Kompletný kód vrátane rozumnej obslužnej metódy:
package sk.upjs.ics.novotnyr.spring;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class DateService {
@Value("${date.format}")
private String format;
public String getDate() {
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
String formattedDateString = dateFormat.format(new Date());
return formattedDateString;
}
}
Triedu sme anotovali ako @Component
, aby sme ju konfigurácii vedeli automaticky zdetekovať a zaviesť do aplikačného kontextu bez explicitnej deklarácie.
Konfigurácia aplikačného kontextu
Aplikačný kontext nakonfigurujeme v kóde, pomocou triedy anotovanej pomocou @Configuration
.
Okrem toho ju anotujeme cez @ComponentScan
, aby sme automaticky odhalili všetky beany (u nás všetky … jeden) v príslušnom balíčku.
Dve požiadavky
Dôležité je, že injektáž do premenných vyšperkovaných pomocou @Value
prebehne, len ak v aplikačnom kontexte zaregistrujete vlastný PropertySourcesPlaceholderConfigurer
. Tomu poviete, z ktorého .properties
súboru sa majú ťahať hodnoty pre injektáž.
Registrácia prebehne klasickým mechanizmom metódy anotovanej ako @Bean
. Pozor však! @Bean
oidné metódy, čo vracajú BeanFactoryPostProcessor
y, musia byť statické. (pozri dokumentáciu, špeciálne stať „A note on BeanFactoryPostProcessor
-returning @Bean
methods”).
Trieda PropertySourcesPlaceholderConfigurer
je BeanFactoryPostProcessor
, čo znamená, že spadá pod uvedené pravidlo.
Kompletný kód:
package sk.upjs.ics.novotnyr.spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
@Configuration
@ComponentScan("sk.upjs.ics.novotnyr.spring")
public class MyApplicationContext {
public static final String DATE_PROPERTIES_PATH = "/sk/upjs/ics/novotnyr/spring/date.properties";
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocation(new ClassPathResource(DATE_PROPERTIES_PATH));
return configurer;
}
}
@PropertySource
Ak si myslíte, že anotácia @PropertySource
to vyrieši za vás, ste na omyle. Tá sa nevzťahuje na injektáž do @Value
. To vysvetlí dokumentácia, ktorá vás odkáže na filozofiu popísanú vyššie.
Kompletný projekt
Stiahnite si ZIP s miniprojektom.