如何在Spring applicationContext中读取系统环境变量

时间:2022-09-24 23:29:20

How to read the system environment variable in the application context?

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

I want something like :

我想要的东西:

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

or

要么

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

depending on the environement.

取决于环境。

Can I have something like this in my application Context?

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

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

where the actual val is set based on the SYSTEM ENVIRONMENT VARIABLE

其中实际的val是根据SYSTEM ENVIRONMENT VARIABLE设置的

I'm using Spring 3.0

我正在使用Spring 3.0

12 个解决方案

#1


47  

Check this article. It gives you several ways to do this, via the PropertyPlaceholderConfigurer which supports external properties (via the systemPropertiesMode property)

看看这篇文章。它通过支持外部属性的PropertyPlaceholderConfigurer(通过systemPropertiesMode属性)为您提供了几种方法。

#2


93  

You are close :o) Spring 3.0 adds Spring Expression Language. You can use

你很接近:o)Spring 3.0增加了Spring Expression Language。您可以使用

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

Combined with java ... -Denv=QA should solve your problem.

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

Note also a comment by @yiling:

另请注意@yiling的评论:

In order to access system environment variable, that is OS level variables as amoe commented, we can simply use "systemEnvironment" instead of "systemProperties" in that EL. Like #{systemEnvironment['ENV_VARIABLE_NAME']}

为了访问系统环境变量,即操作系统级变量,如amoe评论,我们可以简单地在该EL中使用“systemEnvironment”而不是“systemProperties”。就像#{systemEnvironment ['ENV_VARIABLE_NAME']}

#3


30  

Nowadays you can put

现在你可以放

@Autowired
private Environment environment;

in your @Component, @Bean, etc., and then access the properties through the Environment class:

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

environment.getProperty("myProp");

For a single property in a @Bean

对于@Bean中的单个属性

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

Another way are the handy @ConfigurationProperties beans:

另一种方法是方便的@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;
}

Note: Just remember to restart eclipse after setting a new environment variable

注意:请记住在设置新环境变量后重新启动eclipse

#4


24  

Yes, you can do <property name="defaultLocale" value="#{ systemProperties['user.region']}"/> for instance.

是的,你可以做

The variable systemProperties is predefined, see 6.4.1 XML based configuration.

变量systemProperties是预定义的,请参见6.4.1基于XML的配置。

#5


8  

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.

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

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

例如,如果您有一个配置文件

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

then set an environment variable like so:

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

MY_ENV_VAR_PATH=/testapp/config

and your app can load the file using a bean definition like this:

并且您的应用可以使用如下bean定义加载文件:

e.g.

例如

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

#6


7  

Using Spring EL you can eis example write as follows

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

#7


5  

For my use case, I needed to access just the system properties, but provide default values in case they are undefined.

对于我的用例,我只需要访问系统属性,但是在未定义的情况下提供默认值。

This is how you do it:

这是你如何做到的:

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

#8


4  

Declare the property place holder as follows

如下声明属性占位符

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

Then lets say you want to read System.property("java.io.tmpdir") for your Tomcat bean or any bean then add following in your properties file:

然后假设您要为Tomcat bean或任何bean读取System.property(“java.io.tmpdir”),然后在属性文件中添加以下内容:

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

#9


1  

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>

But remember spring gets loaded first and then it will load this bean MethodInvokingFactoryBean. So if you are trying to use this for your test case then make sure that you use depends-on. For e.g. in this case

但请记住spring首先加载然后它将加载此bean MethodInvokingFactoryBean。因此,如果您尝试将此用于测试用例,请确保使用依赖项。对于例如在这种情况下

In case you are using it for your main class better to set this property using your pom.xml as

如果您将它用于主类,最好使用pom.xml设置此属性

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

#10


1  

You can mention your variable attributes in a property file and define environment specific property files like local.properties, production.propertied etc.

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

Now based on the environment, one of these property file can be read in one the listeners invoked at startup, like the ServletContextListener.

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

The property file will contain the the environment specific values for various keys.

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

Sample "local.propeties"

示例“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

Sample "production.properties"

示例“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

For using these properties file, you can make use of REsource as mentioned below

要使用这些属性文件,您可以使用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 can be defined as the environment variable with appropriate values for local and production environment.

SERVER_TYPE可以定义为具有适用于本地和生产环境的值的环境变量。

With these changes the appplicationContext.xml will have the following changes

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

Hope this helps .

希望这可以帮助 。

#11


0  

Thanks to @Yiling. That was a hint.

感谢@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>

After this, you should have one environment variable named 'FILE_PATH'. Make sure you restart your machine after creating that environment variable.

在此之后,您应该有一个名为“FILE_PATH”的环境变量。确保在创建该环境变量后重新启动计算机。

#12


-2  

To get a value of system variable, Simpy use below code:

要获得系统变量的值,Simpy使用下面的代码:

System.getenv("property-name");

#1


47  

Check this article. It gives you several ways to do this, via the PropertyPlaceholderConfigurer which supports external properties (via the systemPropertiesMode property)

看看这篇文章。它通过支持外部属性的PropertyPlaceholderConfigurer(通过systemPropertiesMode属性)为您提供了几种方法。

#2


93  

You are close :o) Spring 3.0 adds Spring Expression Language. You can use

你很接近:o)Spring 3.0增加了Spring Expression Language。您可以使用

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

Combined with java ... -Denv=QA should solve your problem.

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

Note also a comment by @yiling:

另请注意@yiling的评论:

In order to access system environment variable, that is OS level variables as amoe commented, we can simply use "systemEnvironment" instead of "systemProperties" in that EL. Like #{systemEnvironment['ENV_VARIABLE_NAME']}

为了访问系统环境变量,即操作系统级变量,如amoe评论,我们可以简单地在该EL中使用“systemEnvironment”而不是“systemProperties”。就像#{systemEnvironment ['ENV_VARIABLE_NAME']}

#3


30  

Nowadays you can put

现在你可以放

@Autowired
private Environment environment;

in your @Component, @Bean, etc., and then access the properties through the Environment class:

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

environment.getProperty("myProp");

For a single property in a @Bean

对于@Bean中的单个属性

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

Another way are the handy @ConfigurationProperties beans:

另一种方法是方便的@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;
}

Note: Just remember to restart eclipse after setting a new environment variable

注意:请记住在设置新环境变量后重新启动eclipse

#4


24  

Yes, you can do <property name="defaultLocale" value="#{ systemProperties['user.region']}"/> for instance.

是的,你可以做

The variable systemProperties is predefined, see 6.4.1 XML based configuration.

变量systemProperties是预定义的,请参见6.4.1基于XML的配置。

#5


8  

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.

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

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

例如,如果您有一个配置文件

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

then set an environment variable like so:

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

MY_ENV_VAR_PATH=/testapp/config

and your app can load the file using a bean definition like this:

并且您的应用可以使用如下bean定义加载文件:

e.g.

例如

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

#6


7  

Using Spring EL you can eis example write as follows

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

#7


5  

For my use case, I needed to access just the system properties, but provide default values in case they are undefined.

对于我的用例,我只需要访问系统属性,但是在未定义的情况下提供默认值。

This is how you do it:

这是你如何做到的:

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

#8


4  

Declare the property place holder as follows

如下声明属性占位符

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

Then lets say you want to read System.property("java.io.tmpdir") for your Tomcat bean or any bean then add following in your properties file:

然后假设您要为Tomcat bean或任何bean读取System.property(“java.io.tmpdir”),然后在属性文件中添加以下内容:

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

#9


1  

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>

But remember spring gets loaded first and then it will load this bean MethodInvokingFactoryBean. So if you are trying to use this for your test case then make sure that you use depends-on. For e.g. in this case

但请记住spring首先加载然后它将加载此bean MethodInvokingFactoryBean。因此,如果您尝试将此用于测试用例,请确保使用依赖项。对于例如在这种情况下

In case you are using it for your main class better to set this property using your pom.xml as

如果您将它用于主类,最好使用pom.xml设置此属性

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

#10


1  

You can mention your variable attributes in a property file and define environment specific property files like local.properties, production.propertied etc.

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

Now based on the environment, one of these property file can be read in one the listeners invoked at startup, like the ServletContextListener.

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

The property file will contain the the environment specific values for various keys.

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

Sample "local.propeties"

示例“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

Sample "production.properties"

示例“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

For using these properties file, you can make use of REsource as mentioned below

要使用这些属性文件,您可以使用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 can be defined as the environment variable with appropriate values for local and production environment.

SERVER_TYPE可以定义为具有适用于本地和生产环境的值的环境变量。

With these changes the appplicationContext.xml will have the following changes

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

Hope this helps .

希望这可以帮助 。

#11


0  

Thanks to @Yiling. That was a hint.

感谢@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>

After this, you should have one environment variable named 'FILE_PATH'. Make sure you restart your machine after creating that environment variable.

在此之后,您应该有一个名为“FILE_PATH”的环境变量。确保在创建该环境变量后重新启动计算机。

#12


-2  

To get a value of system variable, Simpy use below code:

要获得系统变量的值,Simpy使用下面的代码:

System.getenv("property-name");