Spring applicationContextでシステム環境変数を読み取る方法


116

アプリケーションコンテキストでシステム環境変数を読み取る方法は?

私は次のようなものが欲しい:

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

または

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

環境によって異なります。

アプリケーションコンテキストにこのようなものを含めることはできますか?

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

ここで、実際の値はSYSTEM ENVIRONMENT VARIABLEに基づいて設定されます

Spring 3.0を使用しています

回答:



106

あなたは近いです:o)Spring 3.0はSpring Expression Languageを追加します。使用できます

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

と組み合わせるとjava ... -Denv=QA問題が解決するはずです。

@yilingによるコメントにも注意してください。

システム環境変数、つまりamoeがコメントしたOSレベル変数にアクセスするには、そのELで「systemProperties」の代わりに「systemEnvironment」を使用するだけです。お気に入り #{systemEnvironment['ENV_VARIABLE_NAME']}


java ... -Denv = QAはどういう意味ですか?
fresh_dev

2
Javaシステムプロパティ値を設定します。次のようなコードでこの値を読み取ることができますassert System.getProperty("env") == "QA";
amra

私はこの答えは正しくないと思います。これは、システム環境変数(つまりexport、で設定されたOSレベルの変数など)の読み取りを許可せず、Javaシステムプロパティの読み取りのみを許可します。
amoe 2013年

2
-Dprop = ...は、コマンドラインでJavaプロパティを設定します。このプロパティはを介して読み取ることができますSystem.getProperty("prop")。OSプロパティを読みたい場合は、を使用してくださいSystem.getenv("os-env-variable")。javadocを参照してください:docs.oracle.com/javase/6/docs/api/java/lang/System.html
amra

22
システム環境変数、つまりamoeがコメントしたOSレベル変数にアクセスするには、そのELで「systemProperties」の代わりに「systemEnvironment」を使用するだけです。のように#{systemEnvironment['ENV_VARIABLE_NAME']}
Yiling 2014

51

この頃は置くことができます

@Autowired
private Environment environment;

あなたに@Component@Beanなど、その後を通じてプロパティにアクセスするEnvironmentクラス:

environment.getProperty("myProp");

単一のプロパティのために Aで@Bean

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

別の方法は便利な@ConfigurationProperties豆です:

@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を再起動することを忘れないでください


1
env変数もEnvironmentインターフェイスからアクセスできますか?
Nikhil Sahu 2016

@NikhilSahuはい、そうです。クエリを実行するときと同じキーを使用してこれらにアクセスします。java.lang.Systemたとえば、OSのタイプを取得するために、のインスタンスであるとenv.getProperty("os.name")想定しenvますorg.springframework.core.env.Environment
Ninetou 2017年

1
@Autowired private Environment environment;Componentの場合は機能しません。環境は常にnullです
a_horse_with_no_name

26

はい、<property name="defaultLocale" value="#{ systemProperties['user.region']}"/>例えばあなたがすることができます。

変数systemPropertiesは事前定義されています。6.4.1XML ベースの構成を参照してください。


8

Beanの定義に、必ず「searchSystemEnvironment」を含め、「true」に設定してください。また、それを使用してファイルへのパスを作成する場合は、file:/// urlとして指定します。

たとえば、設定ファイルが

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

8

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>

5

私の使用例では、システムプロパティのみにアクセスする必要がありましたが、それらが未定義の場合に備えてデフォルト値を提供しました。

これがあなたのやり方です:

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

4

プロパティプレースホルダーを次のように宣言します。

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

次にSystem.property("java.io.tmpdir")、Tomcat Beanまたは任意のBean を読み取り、プロパティファイルに以下を追加するとします。

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

1

これがあなたのやり方です:

<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が読み込まれることに注意してください。したがって、これをテストケースに使用する場合は、depends-onを使用していることを確認してください。たとえばこの場合

メインクラスに使用する場合は、pom.xmlを使用してこのプロパティを設定することをお勧めします。

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

1

プロパティファイルで変数属性に言及し、local.properties、production.propertiedなどの環境固有のプロパティファイルを定義できます。

これで、環境に基づいて、これらのプロパティファイルの1つを、ServletContextListenerのように、起動時に呼び出されるリスナーの1つで読み取ることができます。

プロパティファイルには、さまざまなキーの環境固有の値が含まれます。

「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は、ローカル環境と本番環境に適切な値を持つ環境変数として定義できます。

これらの変更により、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}" />

お役に立てれば 。


1

@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」という名前の環境変数が1つ必要です。その環境変数を作成した後、必ずターミナル/ IDEを再起動してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.