Ako injektovať do inštančných premenných beanov hodnoty z _properties_ súborov?

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
  • 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.

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *