如何在 Spring application/context 中读取系统环境变量

如何在应用程式内容中阅读系统环境变量?

我想要这样的东西:

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

or

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

视乎环境而定。

我可以在我的应用程序上下文中使用类似的东西吗?

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

实际的 val 是基于系统环境变量设置的

我用的是 Spring 3.0

331991 次浏览

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

变量 System 属性是预定义的,请参见 6.4.1基于 XML 的配置

你接近了: o) Spring 3.0添加了 Spring 表达式语言。 你可以用

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

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

还要注意@yling 的一条评论:

为了进入系统环境变量,这是操作系统级别 变量,我们可以简单地使用“ systemEnvironment” 而不是那个 EL 中的“ systemProperties” #{systemEnvironment['ENV_VARIABLE_NAME']}

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

In your bean definition, make sure to include "searchSystemEnvironment" and set it to "true". And if you're using it to build a path to a file, specify it as a file:/// url.

So for example, if you have a config file located in

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

然后像这样设定一个环境变量:

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>

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

你要这么做:

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

使用 SpringEL,您可以按以下方式进行 就是个例子写操作

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

This is how you do it:

<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。因此,如果您试图在测试用例中使用它,那么请确保您使用了 Deply-on。例如,在这个例子中

如果您正在为主类使用它,那么最好将 pom.xml 设置为

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

现在你可以把

@Autowired
private Environment environment;

然后通过 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;
}

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

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

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

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

Sample "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 可以定义为具有适合本地和生产环境的适当值的环境变量。

通过这些更改,applicationContext.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}" />

希望这个能帮上忙。

按以下方式声明属性占位符

<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}

感谢@Yling,这是一个暗示。

<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”的环境变量。确保在创建环境变量之后重新启动终端/IDE。

更新版本(2020)。

Use Getenv (“ ENV _ VARIABLE”)