як читати змінну системного середовища у 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" />

де фактична величина встановлюється на основі СИСТЕМНОЇ ЕКОЛОГІЧНОЇ ВІДМІННОСТІ

Я використовую Spring 3.0

Відповіді:



106

Ви близькі: o) Spring 3.0 додає мову Spring Expression . Можна використовувати

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

У поєднанні з цим java ... -Denv=QAслід вирішити вашу проблему.

Зауважте також коментар @yiling:

Для доступу до змінної системного середовища, тобто до змінних рівня ОС, як коментує аме, ми можемо просто використовувати "systemEnvironment" замість "systemProperties" у цій EL. Подібно до #{systemEnvironment['ENV_VARIABLE_NAME']}


що ява ... -Denv = QA означає?
fresh_dev

2
Ви встановлюєте значення властивості системи java. Ви можете прочитати це значення у такому коді, якassert System.getProperty("env") == "QA";
amra

Я думаю, що ця відповідь невірна, це не дозволяє читати змінні системного середовища (тобто змінні на рівні ОС, встановлені з exportтощо), він дозволяє лише зчитувати властивості системи Java.
аме

2
-Dprop = ... встановлює властивість java в командному рядку. Ви можете прочитати цю властивість через System.getProperty("prop"). Якщо ви хочете прочитати властивість ОС, тоді використовуйте System.getenv("os-env-variable"). Дивіться javadoc: docs.oracle.com/javase/6/docs/api/java/lang/System.html
amra

22
Для доступу до змінної системного середовища, тобто до змінних рівня ОС, як коментує аме, ми можемо просто використовувати "systemEnvironment" замість "systemProperties" у цій EL. Як #{systemEnvironment['ENV_VARIABLE_NAME']}.
Yiling

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

Примітка. Просто пам’ятайте, щоб перезапустити затемнення після встановлення нової змінної середовища


1
Чи доступні також змінні env через Environmentінтерфейс?
Нікхіл Саху

@NikhilSahu Так, вони є. Ви отримуєте доступ до них тим самим ключем, що і при запиті, java.lang.Systemнаприклад, щоб отримати тип ОС, який ви вважаєте, env.getProperty("os.name")що envце ваш примірник org.springframework.core.env.Environment.
Нінету

1
@Autowired private Environment environment;не працює для мого Componentоточення завжди недійсним
a_horse_with_no_name


8

У своєму визначенні квасолі обов'язково включіть "searchSystemEnvironment" і встановіть його на "true". І якщо ви використовуєте його для побудови шляху до файлу, вкажіть його як файл: /// 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 або будь-якого квасолі, а потім додайте у свій файл властивостей наступне:

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>

Але пам’ятайте, що весна спочатку завантажується, а потім вона завантажить цей боб 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 після створення цієї змінної середовища.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.