PropertyPlaceholderConfigurer and environment variables in .properties files

半世苍凉 提交于 2019-12-18 11:10:02

问题


I have a Spring application-context.xml with PropertyPlaceholderConfigurer to get properties' values from .properties file. Main and test source folders have separate .properties file. The issue is that I need to use environment variables in .properties file. But when I do it in the following way:

property.name=${env.SYSTEM_PROPERTY}

I'm getting the following error:

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'

while placeholder configurer defined as

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

Any ideas how-to make property.name be interpreted as environment variable (and not as placeholder)?

Best regards, Dmitriy.


回答1:


I'd probably change the solution completely: inject the system property directly, as opposed to injecting the property which refers to a system property

E.g.

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

or

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

I use a property placeholder configurer like this

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

You must also remember to pass the parameter into the program using

 -DJAVA_MY_ENV=xyz

This way when you run the production version you can pass one thing and when you are running tests another.

Also what I often what I do is something like this:

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

where environment is prod/stage/test/int/ci/local (1 per environment - you may only have 2 or 3 for now). You can pass the environment variable to the program. Any properties which should be the same regardless of if its production/running on your local pc/tests would be in the someprops.properties property file. Any ones specific to the environment/way its being run as will go in the more specific file (you should put it in the someprops.properties file as well as a default unless overridden mechanism)

E.g. in classpath:someprops.properties

url=www.mysite.com

in classpath:someprops-local.properties

url=localhost

By using this basic idea you can separate tests and the program's normal running properties in a clean manner.




回答2:


Using:

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

Change your:

property.name=${env.SYSTEM_PROPERTY}

To:

property.name=${SYSTEM_PROPERTY}

I'm using Spring 3.0.4.RELEASE, but I have no idea when this was introduced.




回答3:


I used benkiefer's approach, but I had to add a listener to web.xml:

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


来源:https://stackoverflow.com/questions/10324702/propertyplaceholderconfigurer-and-environment-variables-in-properties-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!