2015-10-26 22 views
15

Mam następujący plik konfiguracyjny:Wiosna @Configuration z PropertyPlaceholderConfigurer fasoli nie rozwiąże @Value adnotacji

@Configuration 
public class PropertyPlaceholderConfigurerConfig { 

    @Value("${property:defaultValue}") 
    private String property; 

    @Bean 
    public static PropertyPlaceholderConfigurer ppc() throws IOException { 
     PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); 
     ppc.setLocations(new ClassPathResource("properties/" + property + ".properties")); 
     ppc.setIgnoreUnresolvablePlaceholders(true); 
     return ppc; 
    } 
} 

uruchomię mojej aplikacji z następujących opcji VM:

-Dproperty=propertyValue 

Więc ja jak moja aplikacja do ładowania określonego pliku właściwości podczas uruchamiania. Jednak z jakiegoś powodu na tym etapie adnotacje nie są przetwarzane, a właściwość to null. Z drugiej strony, jeśli mam skonfigurowany PropertyPlaceholderConfigurer poprzez plik xml - wszystko działa idealnie zgodnie z oczekiwaniami. Przykładowy plik XML:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="ignoreResourceNotFound" value="true"/> 
    <property name="location"> 
     <value>classpath:properties/${property:defaultValue}.properties</value> 
    </property> 
</bean> 

Gdyby spróbować wstrzyknąć wartości nieruchomości w innym pliku konfiguracyjnym Wiosna - to jest właściwie wstrzykiwany. Jeśli przeniesię moje tworzenie fasoli PropertyPlaceholderConfigurer do tego pliku konfiguracyjnego - wartość pola ma wartość zerową.

Jako obejście, używam tej linii kodu:

System.getProperties().getProperty("property", "defaultValue") 

który również działa, ale chciałbym wiedzieć, dlaczego takie zachowanie jest występuje i może to jest możliwe, aby przerobić go w inny sposób, ale bez xml?

+1

Najpierw gorąco polecam użycie 'ProperySourcesPlaceholderConfigurer' i użycie' @ PropertySource' na twojej klasie. Po drugie, fasola musi być "statyczna". –

+0

@ M.Deinum '@ PropertySource' działa idealnie dla mnie, ale co jeśli mam niestandardową implementację' ProperySourcesPlaceholderConfigurer'? –

+0

Dlaczego potrzebujesz niestandardowej implementacji. –

Odpowiedz

30

Od wiosny JavaDoc:

Aby rozwiązać $ {...} zastępcze w definicji lub @Value adnotacji wykorzystujących właściwości z PropertySource, trzeba zarejestrować PropertySourcesPlaceholderConfigurer. Dzieje się to automatycznie podczas używania w XML, ale musi być jawnie zarejestrowana za pomocą statycznej metody @Bean podczas korzystania z klas @Configuration. Zobacz sekcję "Praca z wartościami zewnętrznymi" w javadoc @ Configuration i "uwaga na temat metod zwracania BeanFactoryPostProcessor @Bean" w javadoc @ Beana po szczegóły i przykłady.

Próbujesz użyć symbolu zastępczego w bloku kodu wymaganym do włączenia przetwarzania znaków zastępczych.

Zgodnie z tym, co podano w książce @ M. Deinum, należy użyć właściwości PropertySource (domyślna lub niestandardowa implementacja).

Poniższy przykład pokazuje, jak korzystać z właściwości w adnotacji PropertySource, a także jak wprowadzać właściwości z PropertySource w polu.

@Configuration 
@PropertySource(
      value={"classpath:properties/${property:defaultValue}.properties"}, 
      ignoreResourceNotFound = true) 
public class ConfigExample { 

    @Value("${propertyNameFromFile:defaultValue}") 
    String propertyToBeInjected; 

    /** 
    * Property placeholder configurer needed to process @Value annotations 
    */ 
    @Bean 
    public static PropertySourcesPlaceholderConfigurer propertyConfigurer() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 
} 
2

Jeśli uruchomić aplikację za pomocą opcji VM i chcesz uzyskać dostęp do tej opcji w aplikacji trzeba zrobić to nieco inaczej:

@Value("#{systemProperties.property}") 
private String property; 

Twój PropertyPlaceholderConfigurer nie jest świadomy właściwości systemu, również pamiętać, że uzyskują dostęp do właściwości za pomocą $ - co odnosi się do posiadaczy miejsc, a # odnosi się do ziaren, gdzie systemProperties to ziarno.

+0

Niestety nie działa w konfiguracji, w której mam tworzenie fasoli PropertyPlaceholderConfigurer, ale działa w dowolnym inny plik konfiguracyjny –

3

Dla innych nieszczęśników, którzy nie mogli uzyskać to do pracy w niektórych klasach konfiguracji, gdy pracują w innych:

sprawdź, jakie inne fasola masz w tej klasie i jeśli któryś z nich uzyskać instancję wcześniej w ApplicationContext. Usługa ConversionService jest przykładem jednego.W ten sposób utworzono by klasę konfiguracji przed zarejestrowaniem wymaganej rejestracji, co uniemożliwiłoby zastrzyk własności.

Naprawiłem to, przenosząc usługę ConversionService na inną zaimplementowaną klasę konfiguracji.