Как прочитать системную переменную среды в Spring applicationContext - PullRequest
104 голосов
/ 19 октября 2010

Как прочитать системную переменную среды в контексте приложения?

Я хочу что-то вроде:

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

где фактическое значение val устанавливается на основе переменной среды SYSTEM ENVIRONMENT

Я использую Spring 3.0

Ответы [ 11 ]

102 голосов
/ 19 октября 2010

Ты рядом: о) Spring 3.0 добавляет Язык выражений Spring . Вы можете использовать

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

В сочетании с java ... -Denv=QA должен решить вашу проблему.

Обратите внимание также на комментарий @yiling:

Для доступа к системной переменной среды, то есть к уровню ОС переменные, как прокомментировал amoe, мы можем просто использовать "systemEnvironment" вместо "systemProperties" в этом EL. подобно #{systemEnvironment['ENV_VARIABLE_NAME']}

49 голосов
/ 19 октября 2010

Отметьте эту статью . Это дает вам несколько способов сделать это через PropertyPlaceholderConfigurer, который поддерживает внешние свойства (через свойство systemPropertiesMode).

43 голосов
/ 20 апреля 2015

В настоящее время вы можете поставить

@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 после установки новой переменной среды

25 голосов
/ 19 октября 2010

Да, вы можете сделать <property name="defaultLocale" value="#{ systemProperties['user.region']}"/>, например.

Переменная systemProperties предопределена, см. 6.4.1 Конфигурация на основе XML .

8 голосов
/ 06 ноября 2012

В определении вашего бина обязательно включите "searchSystemEnvironment" и установите для него значение "true".И если вы используете его для создания пути к файлу, укажите его как файл: /// 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>
7 голосов
/ 25 марта 2014

Используя Spring EL, вы можете eis пример написать следующим образом

<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 голосов
/ 10 сентября 2013

Для моего случая использования мне нужно было получить доступ только к системным свойствам, но указать значения по умолчанию, если они не определены.

Вот как вы это делаете:

<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 голосов
/ 22 марта 2016

Объявление объекта недвижимости следующим образом

<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 или любого компонента, а затем добавьте следующее в свой файл свойств:

tomcat.tmp.dir=${java.io.tmpdir}
1 голос
/ 18 декабря 2015

Вы можете упомянуть свои переменные атрибуты в файле свойств и определить файлы свойств для конкретной среды, такие как 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 голос
/ 27 марта 2015

Вот как вы это делаете:

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

Но помните, что сначала загружается пружина, а затем она загружает этот компонент MethodInvokingFactoryBean.Поэтому, если вы пытаетесь использовать это в своем тестовом примере, убедитесь, что вы используете в зависимости от.Например, в этом случае

В случае, если вы используете его для своего основного класса, лучше установить это свойство, используя ваш pom.xml как

<systemProperty>
    <name>deployment.env</name>
    <value>dev</value>
</systemProperty>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...