如何在Spring applicationContext中读取System环境variables

如何在应用程序上下文中读取系统环境variables?

我想要的东西是:

<util:properties id="dbProperties" location="classpath:config_DEV/db.properties" /> 

要么

 <util:properties id="dbProperties" location="classpath:config_QA/db.properties" /> 

取决于environement。

我可以在我的应用程序上下文中有这样的东西吗?

 <util:properties id="dbProperties" location="classpath:config_${systemProperties.env}/db.properties" /> 

实际值是根据系统环境variables设置的

我正在使用Spring 3.0

检查这篇文章 。 它通过支持外部属性(通过systemPropertiesMode属性)的PropertyPlaceholderConfigurer为您提供了多种方法来实现这一点,

你很接近:o)Spring 3.0增加了Springexpression式语言 。 您可以使用

 <util:properties id="dbProperties" location="classpath:config_#{systemProperties['env']}/db.properties" /> 

结合java ... -Denv=QA应该可以解决你的问题。

请注意@yiling的评论:

为了访问系统环境variables,即amoe注释的操作系统级variables,我们可以在EL中简单地使用“systemEnvironment”而不是“systemProperties”。 像#{systemEnvironment['ENV_VARIABLE_NAME']}

是的,你可以做<property name="defaultLocale" value="#{ systemProperties['user.region']}"/>例如。

variablessystemProperties是预定义的,参见6.4.1基于XML的configuration 。

现在你可以放

 @Autowired private Environment environment; 

在你的@Component @Bean@Component @Bean等等,然后通过Environment类访问属性:

 environment.getProperty("myProp"); 

对于 @Bean 的单个属性

 @Value("${my.another.property:123}") // value after ':' is the default Integer property; 

另一种方法是方便的@ConfigurationProperties bean:

 @ConfigurationProperties(prefix="my.properties.prefix") public class MyProperties { // value from my.properties.prefix.myProperty will be bound to this variable String myProperty; // and this will even throw a startup exception if the property is not found @javax.validation.constraints.NotNull String myRequiredProperty; //getters } @Component public class MyOtherBean { @Autowired MyProperties myProperties; } 

注意:只要记得在设置一个新的环境variables后重新启动eclipse

在您的bean定义中,确保包含“searchSystemEnvironment”并将其设置为“true”。 如果您使用它来构build文件path,请将其指定为file:/// url。

所以例如,如果你有一个configuration文件位于

 /testapp/config/my.app.config.properties 

然后像这样设置一个环境variables:

 MY_ENV_VAR_PATH=/testapp/config 

你的应用程序可以像这样使用bean定义来加载文件:

例如

 <bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="searchSystemEnvironment" value="true" /> <property name="searchContextAttributes" value="true" /> <property name="contextOverride" value="true" /> <property name="ignoreResourceNotFound" value="true" /> <property name="locations"> <list> <value>file:///${MY_ENV_VAR_PATH}/my.app.config.properties</value> </list> </property> </bean> 

使用Spring EL你可以举例如下写

 <bean id="myBean" class="path.to.my.BeanClass"> <!-- can be overridden with -Dtest.target.host=http://whatever.com --> <constructor-arg value="#{systemProperties['test.target.host'] ?: 'http://localhost:18888'}"/> </bean> 

对于我的用例,我只需要访问系统属性,但是如果它们是未定义的,则提供默认值。

这是你如何做到的:

 <bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="searchSystemEnvironment" value="true" /> </bean> <bean id="myBean" class="path.to.my.BeanClass"> <!-- can be overridden with -Dtest.target.host=http://whatever.com --> <constructor-arg value="${test.target.host:http://localhost:18888}"/> </bean> 

申报财产占位符如下

 <bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="locations"> <list> <value>file:///path.to.your.app.config.properties</value> </list> </property> </bean> 

然后让我们说你想为你的Tomcat bean或任何bean读取System.property("java.io.tmpdir") ,然后在你的属性文件中添加以下内容:

 tomcat.tmp.dir=${java.io.tmpdir} 

这是你如何做到的:

 <bean id="systemPrereqs" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" scope="prototype"> <property name="targetObject" value="#{@systemProperties}" /> <property name="targetMethod" value="putAll" /> <property name="arguments"> <util:properties> <prop key="deployment.env">dev</prop> </util:properties> </property> </bean> 

但是记得spring首先被加载,然后它会加载这个Bean MethodInvokingFactoryBean。 所以,如果你正在尝试使用这个testing用例,那么确保你使用depends-on。 例如在这种情况下

如果你使用它作为你的主类,更好的使用你的pom.xml来设置这个属性

 <systemProperty> <name>deployment.env</name> <value>dev</value> </systemProperty> 

您可以在属性文件中提及您的variables属性,并定义特定于环境的属性文件,如local.properties,production.propertied等

现在基于环境,这些属性文件中的一个可以在启动时调用的监听器中读取,如ServletContextListener。

属性文件将包含各种键的环境特定值。

示例“local.propeties”

 db.logsDataSource.url=jdbc:mysql://localhost:3306/logs db.logsDataSource.username=root db.logsDataSource.password=root db.dataSource.url=jdbc:mysql://localhost:3306/main db.dataSource.username=root db.dataSource.password=root 

示例“production.properties”

 db.logsDataSource.url=jdbc:mariadb://111.111.111.111:3306/logs db.logsDataSource.username=admin db.logsDataSource.password=xyzqer db.dataSource.url=jdbc:mysql://111.111.111.111:3306/carsinfo db.dataSource.username=admin db.dataSource.password=safasf@mn 

为了使用这些属性文件,可以使用下面提到的REsource

  PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer(); ResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource("classpath:"+System.getenv("SERVER_TYPE")+"DB.properties"); configurer.setLocation(resource); configurer.postProcessBeanFactory(beanFactory); 

可以将SERVER_TYPE定义为适用于本地和生产环境的环境variables。

通过这些更改,appplicationContext.xml将进行以下更改

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="${db.dataSource.url}" /> <property name="username" value="${db.dataSource.username}" /> <property name="password" value="${db.dataSource.password}" /> 

希望这可以帮助 。

感谢@Yiling。 这是一个暗示。

 <bean id="propertyConfigurer" class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="searchSystemEnvironment" value="true" /> <property name="locations"> <list> <value>file:#{systemEnvironment['FILE_PATH']}/first.properties</value> <value>file:#{systemEnvironment['FILE_PATH']}/second.properties</value> <value>file:#{systemEnvironment['FILE_PATH']}/third.properties</value> </list> </property> </bean> 

在此之后,你应该有一个名为“FILE_PATH”的环境variables。 确保在创build该环境variables后重新启动机器。

为了得到系统variables的值,Simpy使用下面的代码:

 System.getenv("property-name");