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
.propertiessú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! @Beanoidné metódy, čo vracajú BeanFactoryPostProcessory, 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.