13

Ho un application-context.xml di primavera con PropertyPlaceholderConfigurer per ottenere i valori delle proprietà dal file .properties. Le cartelle di origine principale e di test hanno un file .properties separato. Il problema è che ho bisogno di usare le variabili d'ambiente nel file .properties. Ma quando lo faccio nel modo seguente:PropertyPlaceholderConfigurer e variabili di ambiente nei file .properties

property.name=${env.SYSTEM_PROPERTY} 

sto ottenendo il seguente errore:

org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'beanName' defined in class path resource [com/example/applicationContext.xml]: Could not resolve placeholder 'env.SYSTEM_PROPERTY' 

mentre segnaposto configuratore definito come

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="location" value="classpath:com/example/application.properties"/> 
</bean> 

Tutte le idee come-fare property.name deve essere interpretato come variabile di ambiente (e non come segnaposto)?

Cordiali saluti, Dmitriy.

risposta

23

avrei probabilmente cambiare la soluzione completamente: iniettare la proprietà di sistema direttamente, al contrario di iniettare la proprietà che si riferisce ad una proprietà di sistema

Ad es

@Value("#{ systemProperties['JAVA_MY_ENV'] }") 
private String myVar; 

o

<property name ="myVar" value="#{systemProperties['JAVA_MY_ENV']}"/> 

Io uso un configuratore di proprietà segnaposto come questo

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="locations"> 
    <list> 
     <value>classpath:someprops.properties</value> 
    </list> 
    </property> 
    <property name="ignoreResourceNotFound" value="true" /> 
    <property name="searchSystemEnvironment" value="true" /> 
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> 

Si deve anche ricordarsi di passare il parametro nel programma utilizzando

-DJAVA_MY_ENV=xyz 

Questo modo quando tu eseguire la versione di produzione è possibile passare una cosa e quando si esegue test un'altra.

anche quello che spesso ciò che faccio è qualcosa di simile:

<property name="locations"> 
    <list> 
     <value>classpath:someprops.properties</value> 
     <value>classpath:someprops-{environment}.properties</value> 
    </list> 
    </property> 

dove l'ambiente è prod/stadio/test/int/CI/locale (1 per l'ambiente - si può avere solo 2 o 3 per adesso). È possibile passare la variabile di ambiente al programma. Qualsiasi proprietà che dovrebbe essere la stessa indipendentemente dal fatto che la sua produzione/esecuzione sul pc/test locale si trovi nel file delle proprietà someprops.properties. Qualsiasi specifico per l'ambiente/modo in cui viene eseguito come andrà nel file più specifico (dovresti metterlo nel file someprops.properties e in un meccanismo predefinito, a meno che non venga sostituito)

E.g. nel classpath: someprops.properties

url=www.mysite.com 

nel classpath: someprops-local.properties

url=localhost 

Utilizzando questa idea di base è possibile separare i test e le normali caratteristiche di scorrimento del programma in modo pulito.

+0

Questo è abbastanza buono. Tuttavia, un problema è che dimenticando di definire una variabile di runtime produce errori di runtime complessi, come il file config_xxx non trovato e i mi piace. Per migliorare questa situazione, registro un bean che implementa speciali interfacce di primavera come questa: class EnvironmentReporter implementa PriorityOrdered, BeanFactoryPostProcessor, EnvironmentAware {...} environment.getProperty mi consente di verificare le proprietà previste e di fallire in modo pulito prima che venga raggiunto qualsiasi altro bean creato. – Federico

7

Usando:

<context:property-placeholder location="classpath:env.properties"/> 

Cambia la tua:

property.name=${env.SYSTEM_PROPERTY} 

A:

property.name=${SYSTEM_PROPERTY} 

sto usando Primavera 3.0.4.RELEASE, ma non ho idea di quando questo è stato presentato.

+1

Grazie mille. Ho risolto il problema utilizzando la classe helper che cerca la proprietà VM, quindi la variabile di ambiente e quindi utilizza il valore predefinito. In questo momento è per me un modo più flessibile. Ma grazie ancora, proverò da parte tua la prossima volta che lo farò. –

+1

strano - usando la primavera 3.0.4, questo non sembra funzionare –

0

ho usato l'approccio di benkiefer, ma ho dovuto aggiungere un listener per web.xml:

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
Problemi correlati