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

이 대답이 틀렸다고 생각합니다. 이것은 시스템 환경 변수 (예 :로 설정된 OS 수준 변수 export)를 읽을 수 없으며 Java 시스템 속성을 읽을 수만 있습니다.
amoe

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']}.
이릉

51

요즘에는

@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를 다시 시작하는 것을 잊지 마십시오.


1
환경 변수도 Environment인터페이스를 통해 액세스 할 수 있습니까?
Nikhil Sahu

@NikhilSahu 네, 그렇습니다. 당신은 당신이하고자하는 경우 쿼리 같은 키에 액세스 java.lang.System당신이 할 것 OS 유형 얻을 예를 들어 env.getProperty("os.name")가정이 env의 인스턴스입니다 org.springframework.core.env.Environment.
Ninetou 2017-06-27

1
@Autowired private Environment environment;내 작동하지 않는 Component환경은 항상 널
a_horse_with_no_name

26

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

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


8

빈 정의에 "searchSystemEnvironment"를 포함하고 "true"로 설정해야합니다. 파일 경로를 만드는 데 사용하는 경우 file : /// url로 지정합니다.

예를 들어 설정 파일이있는 경우

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

그런 다음 다음과 같이 환경 변수를 설정하십시오.

MY_ENV_VAR_PATH=/testapp/config

앱은 다음과 같은 빈 정의를 사용하여 파일을로드 할 수 있습니다.

예 :

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

그러나 스프링이 먼저로드 된 다음이 Bean MethodInvokingFactoryBean을로드한다는 것을 기억하십시오. 따라서 테스트 케이스에 이것을 사용하려는 경우 의존성을 사용하는지 확인하십시오. 예를 들어이 경우

메인 클래스에 사용하는 경우 pom.xml을 사용 하여이 속성을 설정하는 것이 더 좋습니다.

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

1

속성 파일에서 변수 속성을 언급하고 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은 로컬 및 프로덕션 환경에 적절한 값을 사용하여 환경 변수로 정의 할 수 있습니다.

이러한 변경으로 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'라는 하나의 환경 변수가 있어야합니다. 해당 환경 변수를 만든 후 터미널 / IDE를 다시 시작해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.