program tip

Spring applicationContext에서 시스템 환경 변수를 읽는 방법

radiobox 2020. 8. 11. 08:15
반응형

Spring applicationContext에서 시스템 환경 변수를 읽는 방법


애플리케이션 컨텍스트에서 시스템 환경 변수를 읽는 방법은 무엇입니까?

나는 다음과 같은 것을 원한다.

<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을 사용하고 있습니다.


이 기사를 확인 하십시오 . PropertyPlaceholderConfigurer외부 속성을 지원 하는 을 통해 (속성을 통해)이를 수행하는 여러 가지 방법을 제공합니다 systemPropertiesMode.


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


요즘에는

@Autowired
private Environment environment;

당신에 @Component, @Bean등, 다음을 통해 속성에 액세스 Environment클래스 :

environment.getProperty("myProp");

단일 속성 의 경우@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를 다시 시작하는 것을 잊지 마십시오.


예, 예 <property name="defaultLocale" value="#{ systemProperties['user.region']}"/>를 들어 할 수 있습니다 .

systemProperties 변수 는 미리 정의되어 있습니다. 6.4.1 XML 기반 구성을 참조하십시오 .


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

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:

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>

Using Spring EL you can eis example write as follows

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

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>

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.tmp.dir=${java.io.tmpdir}

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

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

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

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

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

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

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

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

        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.

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

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


Thanks to @Yiling. That was a hint.

<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 terminal/IDE after creating that environment variable.

참고URL : https://stackoverflow.com/questions/3965446/how-to-read-system-environment-variable-in-spring-applicationcontext

반응형