13

我有一個Spring application-context.xml,使用PropertyPlaceholderConfigurer從.properties文件獲取屬性值。 Main和測試源文件夾具有單獨的.properties文件。問題是我需要在.properties文件中使用環境變量。但是,當我這樣做以下列方式:.properties文件中的PropertyPlaceholderConfigurer和環境變量

property.name=${env.SYSTEM_PROPERTY} 

,我發現了以下錯誤:

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' 

而佔位符配置者定義爲

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

任何想法如何,使property.name被解釋爲環境變量(而不是佔位符)?

最好的問候,德米特里。

回答

23

我可能完全改變溶液:直接噴射系統屬性,而不是注入其指的是系統屬性

例如屬性

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

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

我使用屬性佔位符配置者這樣

<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" /> 

你還必須記住使用

-DJAVA_MY_ENV=xyz 

這對參數傳遞到程序當你的方式運行生產版本,你可以傳遞一件事情,當你正在運行另一個測試時。

也是我經常我做的是這樣的:

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

這裏的環境是督促/臺/測試/ INT/CI /本地(1元環境 - 你可能只有2或3現在)。您可以將環境變量傳遞給程序。無論其在本地pc/tests上的生產/運行是否在someprops.properties屬性文件中,都應該是相同的。任何特定於環境的方式/其運行方式都會在更具體的文件中進行(您應該將其放在someprops.properties文件中以及默認情況下,除非被覆蓋的機制)

E.g. 在類路徑:someprops.properties

url=www.mysite.com 

在類路徑:someprops-local.properties

url=localhost 

通過使用這種基本的想法,你可以在一個乾淨的方式分離試驗和程序的正常運行性能。

+0

這是相當不錯的。然而,一個問題是,忘記定義運行時變量會產生棘手的運行時錯誤,比如找不到config_xxx文件等。爲了改善這種情況,我註冊了一個實現瞭如下特殊彈簧接口的bean:class EnvironmentReporter實現了PriorityOrdered,BeanFactoryPostProcessor,EnvironmentAware {...} environment.getProperty允許我檢查期望的屬性並在任何其他bean獲取之前乾淨地失敗創建。 – Federico 2013-08-16 13:00:21

7

使用:

property.name=${env.SYSTEM_PROPERTY} 

要:

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

您更改

property.name=${SYSTEM_PROPERTY} 

我使用Spring 3.0.4.RELEASE,但我不知道什麼時候該被引入。

+1

非常感謝。我已經解決了使用幫助類的問題,該類尋找VM屬性,然後使用環境變量,然後使用默認值。現在對我來說這是更靈活的方式。但是,還是謝謝,下次我會試試你的方式。 – 2012-06-03 21:39:47

+1

奇怪 - 使用彈簧3.0.4,這似乎不起作用 – 2014-07-17 14:17:00

0

我用benkiefer的做法,但我有一個監聽器添加到web.xml中:

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