2013-01-05 10 views
16

robie to ..Wiosna 3,1 Środowisko nie działa z plikami własności użytkowników

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(context); 
xmlReader 
     .loadBeanDefinitions(new ClassPathResource("SpringConfig.xml")); 
PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer(); 
propertyHolder.setLocation(new ClassPathResource(
     "SpringConfig.properties")); 
context.addBeanFactoryPostProcessor(propertyHolder); 

    ...... 

context.refresh(); 

Teraz w moich plikach @Configuration właściwości obecny w moim SpringConfig.properties nie są coraz podniósł jeśli mogę to zrobić ...

@Autowired 
private Environment env 
..... 
env.getProperty("my.property") 

Ale pojawia że nieruchomość, jeśli mogę użyć

@Value("${my.property}") 
private String myProperty; 

próbowałem nawet dodając kilka więcej linii takich jak to, ale bezużyteczne.

ConfigurableEnvironment env = new StandardEnvironment(); 
propertyHolder.setEnvironment(env); 

Czy ktoś wie, dlaczego moje właściwości nie zostały załadowane do środowiska? Dzięki.

Odpowiedz

13

PropertySourcesPlaceholderConfigurer odczytuje pliki własności bezpośrednio (jak to miało miejsce przez PropertyPlaceholderConfigurer wiosną 3,0 razy), to tylko postprocesor, który nie zmieni sposób właściwości są używane w kontekście wiosennej - w tym przypadku właściwości są dostępne tylko jako definicji fasoli placeholders.

Jest to PropertySourcesPlaceholderConfigurer, który używa środowiska, a nie odwrotnie.

Struktura źródeł nieruchomości działa na poziomie kontekstu aplikacji, podczas gdy konfiguratory symboli zastępczych obiektów udostępniają tylko funkcje do przetwarzania symboli zastępczych w definicjach komponentów bean. Aby skorzystać z właściwości source abstrakcję należy użyć @PropertySource adnotacji tj ozdobić swoją klasę konfiguracji z czymś jak @PropertySource("classpath:SpringConfig.properties")

wierzę, że można to zrobić programowo to samo, czyli można dostać ConfigurableEnvironment kontenera przed kontekst był odświeżony, zmodyfikować jego MutablePropertySources (musisz najpierw uzyskać właściwość AbstractApplicationContextenvironment przez) przez getPropertySources().addFirst(new ResourcePropertySource(new ClassPathResource( "SpringConfig.properties")));, ale jest mało prawdopodobne, co chcesz zrobić - jeśli masz już przypisaną klasę @Configuration, dekorowanie jej za pomocą @PropertySource("classpath:SpringConfig.properties") jest znacznie prostsze.

Jeśli chodzi o instancję PropertySourcesPlaceholderConfigurer - pobierze ona automatycznie źródła właściwości (tak jak implementuje EnvironmentAware) z kontekstu aplikacji, więc wystarczy zarejestrować domyślną instancję.

Dla przykładów realizacji niestandardowego źródła nieruchomość zobaczyć http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/

+0

Przeszedłem przez MutuablePropertySources API, ale to było naprawdę dziwne, czuję Wiosna hasn sprawił, że obsługa nieruchomości była łatwa i piękna. Ale mówisz, że jest mało prawdopodobne, że chcę to zrobić, dlaczego nie? Jeśli to działa, mogę spróbować. Powód Myślałem, że moje właściwości będą w środowisku po przeczytaniu tego artykułu .. [http://www.javaworld.com/community/node/8309](http://www.javaworld.com/community/node/8309) – endless

+0

@ user1364959 sprawdź http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/ - PS Mówię "mało prawdopodobne", ponieważ samo dekorowanie klasy Conifuguration za pomocą '@PropertySource (" classpath: SpringConfig.properties ")' powinno wystarczyć do dodania źródła właściwości do środowiska. –

+0

Co do PropertySourcesPlaceholderConfigurer - po zarejestrowaniu w kontenerze czegoś takiego jak '@Bean() public static PropertySourcesPlaceholderConfigurer() {..}' automatycznie pobierze źródła właściwości z kontekstu aplikacji (ponieważ implementuje EnvironmentAware). Więc będzie w stanie zastąpić symbole zastępcze w definicjach fasoli. –

3

Dodawanie lokalnych właściwości do PropertySourcesPlaceholderConfigurer (z setProperties() lub setLocation()) nie udostępniać je w Environment.

Właściwie to działa w odwrotny sposób - Environment działa jako podstawowe źródło właściwości (patrz ConfigurableEnvironment) i PropertySourcesPlaceholderConfigurer może właściwości z Environment dostępnych za pomocą ${...} składnię.

0

Zrobiłem to za @Boris sugestii ..

PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer(); 
    ConfigurableEnvironment env = new StandardEnvironment(); 
    env.getPropertySources().addFirst(
      new ResourcePropertySource(new ClassPathResource(
        "SpringConfig.properties"))); 
    propertyHolder.setEnvironment(env); 
    context.addBeanFactoryPostProcessor(propertyHolder); 
      context.register(SpringConfig.class); 
      context.refresh(); 

Teraz w klasach @Configuration wszystkie właściwości (w tym moich własnych i systemu własności) może zostać rozwiązane za pomocą @Value.

Ale środowisko, które dostaje @Aowiani do klasy @Configuration ma tylko właściwości systemowe, a nie SpringConfig.properties I ustawiony jak wyżej. Ale wyraźnie, przed wywołaniem context.refresh() powyżej, ConfigurableEnvironment ma również moje właściwości. Ale po wywołaniu context.refresh() moje właściwości są usuwane ze środowiska, które zostaje automatycznie wpisane w @konfiguracja.

Chcę móc użyć lepszej składni, env.getProperty ("moja_property"). Czy ktoś wie, dlaczego tak się dzieje?

+2

Nie powinieneś tworzyć własnej instancji środowiska. Powinieneś zmodyfikować ten, który ma kontekst aplikacji. P.S. edytuj pytanie o wstawienie go jako odpowiedzi. –

+0

Skorygowałem odpowiedź –

+0

... i czy tworzysz własny kontekst aplikacji przez @Configuration? –

0

Załaduję 2 typy właściwości, jedna jest właściwością Środowisko, a druga to kontekst, z którego zwykle można uzyskać od powiedzmy servletContext.getServletContext(). Moja właściwość środowiska jest zdefiniowana jako: MOD_CONFIG_ROOT, która jest ustawiana osobno dla środowiska, tym samym oddzielając szczegóły lokalizacji pliku ucha, który zawiera kod. Oto konfiguracja. [Uwaga: musiałem załadować pliki własności jak pierwszą rzeczą przed załadowaniem serwletów skorzystać z właściwości używając ${someProperty}]

<bean id="externalProperties" 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="locations"> 
     <list> 
      <value>file:#{ systemEnvironment['MOD_CONFIG_ROOT'] 
       }#{servletContext.contextPath}/users.properties</value> 
     </list> 
    </property> 
    <property name="searchSystemEnvironment" value="true" /> 
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK" /> 
</bean> 
Powiązane problemy