cara membaca variabel lingkungan Sistem di Spring applicationContext


116

Bagaimana membaca variabel lingkungan sistem dalam konteks aplikasi?

Saya ingin sesuatu seperti:

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

atau

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

tergantung pada lingkungan.

Dapatkah saya memiliki sesuatu seperti ini dalam Konteks aplikasi saya?

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

di mana nilai sebenarnya ditetapkan berdasarkan VARIABEL LINGKUNGAN SISTEM

Saya menggunakan Spring 3.0

Jawaban:



106

Anda sudah dekat: o) Spring 3.0 menambahkan Spring Expression Language . Kamu bisa memakai

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

Dikombinasikan dengan java ... -Denv=QAharus menyelesaikan masalah Anda.

Perhatikan juga komentar oleh @yiling:

Untuk mengakses variabel lingkungan sistem, yaitu variabel tingkat OS seperti yang dikomentari, kita cukup menggunakan "systemEnvironment" daripada "systemProperties" di EL itu. Suka #{systemEnvironment['ENV_VARIABLE_NAME']}


apa itu java ... -Denv = QA?
fresh_dev

2
Anda menyetel nilai properti sistem java. Anda dapat membaca nilai ini dalam kode sepertiassert System.getProperty("env") == "QA";
amra

Saya pikir jawaban ini salah, ini tidak memungkinkan membaca variabel lingkungan sistem (yaitu variabel tingkat OS yang diatur dengan export, dll), ini hanya memungkinkan membaca properti sistem Java.
amoe

2
-Dprop = ... menyetel properti java di baris perintah. Anda dapat membaca properti ini melalui System.getProperty("prop"). Jika Anda ingin membaca properti OS, gunakan System.getenv("os-env-variable"). Lihat javadoc: docs.oracle.com/javase/6/docs/api/java/lang/System.html
amra

22
Untuk mengakses variabel lingkungan sistem, yaitu variabel tingkat OS seperti yang dikomentari, kita cukup menggunakan "systemEnvironment" daripada "systemProperties" di EL itu. Suka #{systemEnvironment['ENV_VARIABLE_NAME']}.
Yiling

51

Saat ini Anda bisa menempatkan

@Autowired
private Environment environment;

di Anda @Component,, @Beandll., lalu akses properti melalui Environmentkelas:

environment.getProperty("myProp");

Untuk satu properti di a@Bean

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

Cara lain adalah @ConfigurationPropertieskacang praktis :

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

Catatan: Ingatlah untuk memulai ulang eclipse setelah menyetel variabel lingkungan baru


1
Apakah variabel env juga dapat diakses melalui Environmentantarmuka?
Nikhil Sahu

@NikhilSahu Ya, mereka. Anda mengaksesnya dengan kunci yang sama seperti yang Anda lakukan saat melakukan kueri, java.lang.Systemmisalnya untuk mendapatkan jenis OS yang Anda env.getProperty("os.name")anggap sebagai envinstance Anda org.springframework.core.env.Environment.
Sembilan puluh

1
@Autowired private Environment environment;tidak bekerja untuk Componentlingkungan saya selalu null
a_horse_with_no_name

26

Ya, Anda bisa melakukannya <property name="defaultLocale" value="#{ systemProperties['user.region']}"/>misalnya.

Variabel systemProperties sudah ditentukan sebelumnya, lihat 6.4.1 konfigurasi berbasis XML .


8

Dalam definisi kacang Anda, pastikan untuk menyertakan "searchSystemEnvironment" dan setel ke "true". Dan jika Anda menggunakannya untuk membuat jalur ke file, tentukan sebagai file: /// url.

Jadi misalnya, jika Anda memiliki file konfigurasi yang terletak di

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

kemudian atur variabel lingkungan seperti ini:

MY_ENV_VAR_PATH=/testapp/config

dan aplikasi Anda dapat memuat file menggunakan definisi kacang seperti ini:

misalnya

<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

Menggunakan Spring EL Anda dapat melihat contoh tulis sebagai berikut

<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

Untuk kasus penggunaan saya, saya hanya perlu mengakses properti sistem, tetapi memberikan nilai default jika tidak ditentukan.

Beginilah cara Anda melakukannya:

<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

Nyatakan pemilik tempat properti sebagai berikut

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

Kemudian katakanlah Anda ingin membaca System.property("java.io.tmpdir")untuk kacang Tomcat atau kacang apa pun lalu tambahkan berikut ini di file properti Anda:

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

1

Beginilah cara Anda melakukannya:

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

Tapi ingat musim semi dimuat terlebih dahulu dan kemudian itu akan memuat kacang ini MethodInvokingFactoryBean. Jadi jika Anda mencoba menggunakan ini untuk kasus pengujian Anda, maka pastikan bahwa Anda menggunakan tergantung. Misalnya dalam kasus ini

Jika Anda menggunakannya untuk kelas utama Anda, sebaiknya setel properti ini menggunakan pom.xml Anda sebagai

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

1

Anda dapat menyebutkan atribut variabel Anda dalam file properti dan menentukan file properti khusus lingkungan seperti local.properties, production.propertied, dll.

Sekarang berdasarkan lingkungan, salah satu file properti ini dapat dibaca di salah satu pemroses yang dipanggil saat startup, seperti ServletContextListener.

File properti akan berisi nilai spesifik lingkungan untuk berbagai kunci.

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

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

Untuk menggunakan file properti ini, Anda dapat menggunakan REsource seperti yang disebutkan di bawah ini

        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 dapat didefinisikan sebagai variabel lingkungan dengan nilai yang sesuai untuk lingkungan lokal dan produksi.

Dengan perubahan ini, appplicationContext.xml akan memiliki perubahan berikut

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

Semoga ini membantu .


1

Terima kasih kepada @Yiling. Itu adalah petunjuk.

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

Setelah ini, Anda harus memiliki satu variabel lingkungan bernama 'FILE_PATH'. Pastikan Anda memulai ulang terminal / IDE Anda setelah membuat variabel lingkungan itu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.