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>