come leggere la variabile di ambiente di sistema in Spring applicationContext


116

Come leggere la variabile di ambiente di sistema nel contesto dell'applicazione?

Voglio qualcosa come:

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

o

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

a seconda dell'ambiente.

Posso avere qualcosa di simile nel contesto della mia applicazione?

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

dove il valore effettivo è impostato in base alla VARIABILE AMBIENTE DEL SISTEMA

Sto usando Spring 3.0

Risposte:



106

Sei vicino: o) Spring 3.0 aggiunge Spring Expression Language . Puoi usare

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

Combinato con java ... -Denv=QAdovrebbe risolvere il tuo problema.

Nota anche un commento di @yiling:

Per accedere alla variabile di ambiente del sistema, cioè le variabili a livello di sistema operativo come ha commentato amoe, possiamo semplicemente usare "systemEnvironment" invece di "systemProperties" in quel EL. Piace #{systemEnvironment['ENV_VARIABLE_NAME']}


cosa significa java ... -Denv = QA?
fresh_dev

2
Si imposta un valore della proprietà di sistema java. Puoi leggere questo valore in un codice comeassert System.getProperty("env") == "QA";
amra

Penso che questa risposta non sia corretta, ciò non consente la lettura delle variabili di ambiente di sistema (cioè le variabili a livello di sistema operativo impostate con export, ecc.), Consente solo la lettura delle proprietà del sistema Java.
amoe

2
-Dprop = ... imposta una proprietà java nella riga di comando. Puoi leggere questa proprietà tramite System.getProperty("prop"). Se desideri leggere una proprietà del sistema operativo, usa System.getenv("os-env-variable"). Vedi javadoc: docs.oracle.com/javase/6/docs/api/java/lang/System.html
amra

22
Per accedere alla variabile di ambiente del sistema, cioè le variabili a livello di sistema operativo come ha commentato amoe, possiamo semplicemente usare "systemEnvironment" invece di "systemProperties" in quel EL. Mi piace #{systemEnvironment['ENV_VARIABLE_NAME']}.
Yiling

51

Al giorno d'oggi puoi mettere

@Autowired
private Environment environment;

nella vostra @Component, @Beane così via, e poi accedere alle proprietà tramite la Environmentclasse:

environment.getProperty("myProp");

Per un unico immobile in a@Bean

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

Un altro modo sono i @ConfigurationPropertiesfagioli utili :

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

Nota: ricorda di riavviare eclipse dopo aver impostato una nuova variabile di ambiente


1
Le variabili env sono accessibili anche tramite l' Environmentinterfaccia?
Nikhil Sahu

@NikhilSahu Sì, lo sono. Puoi accedervi con la stessa chiave che faresti quando interroghi, java.lang.Systemad esempio, per ottenere il tipo di sistema operativo che faresti env.getProperty("os.name")supponendo che envsia la tua istanza org.springframework.core.env.Environment.
Ninetou

1
@Autowired private Environment environment;non funziona per il mio Componentambiente è sempre nullo
a_horse_with_no_name


8

Nella definizione del bean, assicurarsi di includere "searchSystemEnvironment" e impostarlo su "true". E se lo stai usando per creare un percorso a un file, specificalo come file: /// url.

Quindi, ad esempio, se hai un file di configurazione situato in

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

quindi imposta una variabile d'ambiente in questo modo:

MY_ENV_VAR_PATH=/testapp/config

e la tua app può caricare il file utilizzando una definizione di bean come questa:

per esempio

<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

Usando Spring EL puoi scrivere un esempio come segue

<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

Per il mio caso d'uso, avevo bisogno di accedere solo alle proprietà di sistema, ma fornire valori predefiniti nel caso in cui non fossero definiti.

Ecco come lo fai:

<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

Dichiarare il segnaposto della proprietà come segue

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

Quindi diciamo che vuoi leggere System.property("java.io.tmpdir")per il tuo bean Tomcat o qualsiasi bean, quindi aggiungi quanto segue nel tuo file delle proprietà:

tomcat.tmp.dir=${java.io.tmpdir}

1

Ecco come lo fai:

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

Ma ricorda che prima viene caricata la primavera e poi caricherà questo bean MethodInvokingFactoryBean. Quindi, se stai cercando di usarlo per il tuo caso di test, assicurati di utilizzare dipende da. Ad esempio in questo caso

Nel caso in cui lo stai usando per la tua classe principale, meglio impostare questa proprietà usando il tuo pom.xml come

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

1

È possibile menzionare gli attributi della variabile in un file di proprietà e definire file di proprietà specifici dell'ambiente come local.properties, production.propertied ecc.

Ora, in base all'ambiente, uno di questi file di proprietà può essere letto in uno dei listener richiamati all'avvio, come ServletContextListener.

Il file delle proprietà conterrà i valori specifici dell'ambiente per varie chiavi.

Esempio di "proprietà.locali"

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

Esempio di "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

Per utilizzare questi file delle proprietà, è possibile utilizzare REsource come indicato di seguito

        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 può essere definita come la variabile di ambiente con valori appropriati per l'ambiente locale e di produzione.

Con queste modifiche, appplicationContext.xml avrà le seguenti modifiche

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

Spero che questo ti aiuti .


1

Grazie a @Yiling. Questo era un suggerimento.

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

Dopo questo, dovresti avere una variabile d'ambiente chiamata "FILE_PATH". Assicurati di riavviare il tuo terminale / IDE dopo aver creato quella variabile d'ambiente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.