如何在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");