2013-01-05 11 views
16

sto facendo questo ..Primavera 3.1 Ambiente non funziona con i file di proprietà degli utenti

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(); 

Ora nei miei file @Configuration, le proprietà presenti nelle mie SpringConfig.properties non sono sempre raccolti se faccio questo ...

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

ma ottengo che la proprietà se uso

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

ho anche provato ad aggiungere paio di più linee come questa, ma inutili.

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

Qualcuno sa perché le mie proprietà non sono caricate nell'ambiente? Grazie.

risposta

13

PropertySourcesPlaceholderConfigurer legge direttamente i file delle proprietà (come è stato fatto da PropertyPlaceholderConfigurer in Spring 3.0 volte), è solo un postprocessore che non cambia il modo in cui le proprietà vengono utilizzate nel contesto Spring - in questo caso le proprietà sono disponibili solo come definizione del bean segnaposto.

È PropertySourcesPlaceholderConfigurer che utilizza Ambiente e non viceversa.

Il framework delle proprietà delle proprietà funziona a livello di contesto dell'applicazione, mentre i configuratori di segnaposto delle proprietà forniscono solo la funzionalità per elaborare i segnaposto nelle definizioni dei bean. Per utilizzare proprietà source astrazione si dovrebbe usare @PropertySource annotazione cioè decorare la vostra classe di configurazione con qualcosa di simile @PropertySource("classpath:SpringConfig.properties")

Io credo che si può fare la stessa cosa a livello di codice, per esempio, si può ottenere ConfigurableEnvironment del contenitore prima che il contesto era rinfrescata, modificare la sua MutablePropertySources (è necessario prima ottenere AbstractApplicationContextenvironment proprietà tramite context.getEnvironment()) tramite getPropertySources().addFirst(new ResourcePropertySource(new ClassPathResource( "SpringConfig.properties"))); ma è improbabile che cosa si vuole fare - se si dispone già di una classe annotata @Configuration, decorarla con @PropertySource("classpath:SpringConfig.properties") è molto più semplice.

Come per l'istanza PropertySourcesPlaceholderConfigurer, recupera automaticamente le origini delle proprietà (come implementa EnvironmentAware) dal contesto dell'applicazione, quindi è sufficiente registrare un'istanza predefinita.

Per gli esempi di implementazione fonte proprietà personalizzata vedere http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/

+0

sono andato tramite l'API MutuablePropertySources, ma era veramente confusa, mi sento Primavera hasn 'ha reso la gestione della proprietà facile e bella. Ma tu dici che è improbabile che io voglia farlo, perché no? Se funziona, posso provarci. Il motivo per cui ho pensato che le mie proprietà si trovassero nell'ambiente è stato dopo aver letto questo articolo .. [http://www.javaworld.com/community/node/8309](http://www.javaworld.com/community/node/8309) – endless

+0

@ user1364959 si prega di controllare http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/ - PS Sto dicendo "improbabile" perché la semplice decorazione della classe Conifugurazione con '@PropertySource (" classpath: SpringConfig.properties ")' dovrebbe essere sufficiente per aggiungere l'origine della proprietà all'ambiente. –

+0

Come per PropertySourcesPlaceholderConfigurer - quando si registra uno nel contenitore con qualcosa come '@Bean() public static PropertySourcesPlaceholderConfigurer() {..}' recupererà automaticamente le origini delle proprietà dal contesto dell'applicazione (poiché implementa EnvironmentAware). Quindi sarà in grado di sostituire i segnaposto nelle definizioni dei bean. –

3

calcolata locali proprietà alla PropertySourcesPlaceholderConfigurer (con setProperties() o setLocation()) non li rende disponibili in Environment.

realtà funziona in modo opposto - Environment agisce come una fonte primaria di proprietà (vedi ConfigurableEnvironment), e può fare PropertySourcesPlaceholderConfigurer proprietà dal Environment disponibile utilizzando ${...} sintassi.

0

Ho fatto questo per @Boris suggerimento ..

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(); 

Ora nelle classi @Configuration tutte le proprietà (compreso il mio sistema e le proprietà) può essere risolto usando @Value.

Ma l'Ambiente che ottiene @Autowired nella classe @Configuration ha solo proprietà di sistema al suo interno, non SpringConfig.properties che ho impostato come sopra. Ma chiaramente, prima di chiamare context.refresh() sopra, il ConfigurableEnvironment ha anche le mie proprietà. Ma una volta chiamato context.refresh(), le mie proprietà vengono rimosse dall'ambiente che viene eseguito automaticamente in @Configuration.

Voglio essere in grado di utilizzare la sintassi migliore, env.getProperty ("my.property"). Qualcuno sa perché questo è il caso?

+2

Non si dovrebbe creare la propria istanza di Ambiente. È necessario modificare quello che ha il contesto dell'applicazione. Post scriptum per favore modifica la domanda prima di postarla come risposta. –

+0

Ho modificato la risposta –

+0

... e se stai creando il tuo contesto applicativo tramite @Configuration? –

0

Sto caricando 2 tipi di proprietà una è la proprietà Ambiente e l'altra è il contesto che di solito si ottiene da diciamo servletContext.getServletContext(). La mia proprietà ambiente è definita come: MOD_CONFIG_ROOT che si imposta separatamente nell'ambiente, separando quindi i dettagli della posizione del file ear che contiene il codice. Ecco la configurazione. [Nota: ho dovuto caricare i file di proprietà come prima cosa prima di caricare i servlet di fare uso delle proprietà utilizzando ${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> 
Problemi correlati