web-dev-qa-db-fra.com

comment lire la variable d'environnement système dans Spring applicationContext

Comment lire la variable d'environnement système dans le contexte de l'application?

Je veux quelque chose comme:

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

ou

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

en fonction de l'environnement.

Puis-je avoir quelque chose comme ça dans mon contexte d'application? 

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

où la valeur réelle est définie en fonction de la variable d'environnement système

J'utilise Spring 3.0

96
jai

Vérifiez cet article . Cela vous donne plusieurs façons de le faire, via PropertyPlaceholderConfigurer qui supporte les propriétés externes (via la propriété systemPropertiesMode).

48
Bozho

Vous êtes proche: o) Spring 3.0 ajoute Spring Expression Language . Vous pouvez utiliser 

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

Combiné avec Java ... -Denv=QA devrait résoudre votre problème.

Notez également un commentaire de @yiling:

Pour accéder à la variable d'environnement du système, il s'agit du niveau du système d'exploitation Comme le dit amoe les variables, nous pouvons simplement utiliser "systemEnvironment" au lieu de "systemProperties" dans cette EL. Comme #{systemEnvironment['ENV_VARIABLE_NAME']}

99
amra

Aujourd'hui, vous pouvez mettre  

@Autowired
private Environment environment;

dans votre @Component, @Bean, etc., puis accédez aux propriétés via la classe Environment:

environment.getProperty("myProp");

Pour une seule propriété dans un @Bean

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

Une autre façon sont les beans @ConfigurationProperties pratiques:

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

Remarque: n'oubliez pas de redémarrer Eclipse après avoir défini une nouvelle variable d'environnement.

39
Dariusz

Oui, vous pouvez faire <property name="defaultLocale" value="#{ systemProperties['user.region']}"/> par exemple.

La variable systemProperties est prédéfinie, voir 6.4.1 Configuration basée sur XML .

25
Istao

Dans la définition de votre bean, assurez-vous d'inclure "searchSystemEnvironment" et définissez-le sur "true". Et si vous l'utilisez pour créer un chemin d'accès à un fichier, spécifiez-le en tant que fichier: /// url.

Ainsi, par exemple, si vous avez un fichier de configuration situé dans 

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

puis définissez une variable d'environnement comme suit:

MY_ENV_VAR_PATH=/testapp/config

et votre application peut charger le fichier en utilisant une définition de bean comme celle-ci:

par exemple.

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

En utilisant Spring EL, vous pouvez eis exemple écrire comme suit

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

Pour mon cas d'utilisation, je devais accéder uniquement aux propriétés du système, mais fournir des valeurs par défaut au cas où elles ne seraient pas définies.

Voici comment vous le faites:

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

Déclarez le titulaire de la propriété comme suit

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

Ensuite, disons que vous voulez lire System.property("Java.io.tmpdir") pour votre bean Tomcat ou n’importe quel bean, puis ajouter les éléments suivants dans votre fichier de propriétés:

Tomcat.tmp.dir=${Java.io.tmpdir}
4
Justin Patel

Vous pouvez mentionner vos attributs de variable dans un fichier de propriétés et définir des fichiers de propriétés spécifiques à l'environnement, tels que local.properties, production.propertied, etc.

Désormais, en fonction de l'environnement, l'un de ces fichiers de propriétés peut être lu dans l'un des écouteurs appelés au démarrage, comme ServletContextListener.

Le fichier de propriétés contiendra les valeurs spécifiques à l'environnement pour différentes clés.

Exemple "local.properties"

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

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

Pour utiliser ces fichiers de propriétés, vous pouvez utiliser REsource comme indiqué ci-dessous

        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 peut être défini en tant que variable d'environnement avec les valeurs appropriées pour l'environnement local et l'environnement de production. 

Avec ces modifications, appplicationContext.xml aura les modifications suivantes

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

J'espère que cela t'aides .

1
Sunil

Voici comment vous le faites:

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

Mais rappelez-vous que spring est chargé en premier, puis il charge ce bean MethodInvokingFactoryBean. Donc, si vous essayez de l'utiliser pour votre scénario de test, assurez-vous que vous utilisez des dépendances. Par exemple dans ce cas

Si vous l'utilisez pour votre classe principale, il est préférable de définir cette propriété à l'aide de votre fichier pom.xml.

<systemProperty>
    <name>deployment.env</name>
    <value>dev</value>
</systemProperty>
1
Atit Shah

Merci à @Yiling. C'était un indice.

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

Après cela, vous devriez avoir une variable d’environnement nommée 'FILE_PATH'. Assurez-vous de redémarrer votre terminal/IDE après avoir créé cette variable d’environnement.

0
Jaikrat