Aubergine
Aubergine

Reputation: 6032

How to inject environmental variables inside spring xml configuration?

AWS talks about System.getProperty("JDBC_CONNECTION_STRING") in http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Java.managing.html after we set up our environmental variables. All great except I can't call System.getProperty inside my Spring XML configuration code nor I can call for resource bundle shortcuts since resources bundle itself has to extract somehow these environmental variables to serve them. Could you kindly help me please to convert this example config to use environmental variables ? :-)

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://secrethost:007/whois?autoReconnect=true" />
    <property name="username" value="bond" />
    <property name="password" value="abuginsidemistycorner" />
    <property name="initialSize" value="100" />

    <property name="minEvictableIdleTimeMillis">
        <value>300000</value>
    </property>

    <property name="timeBetweenEvictionRunsMillis">
        <value>60000</value>
    </property>

    <property name="maxIdle" value="20" />
</bean>

I was not able to understand what do people do here:

Can I use an Environment variable based location for Spring FileSystemResource? which would work for recent spring version?

Upvotes: 34

Views: 75262

Answers (3)

M. Deinum
M. Deinum

Reputation: 124441

First add a <context:property-placeholder .. /> element to your configuration.

<context:property-placeholder />

Then simply use placeholders in your config.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="${JDBC_CONNECTION_STRING}" />
    <property name="username" value="bond" />
    <property name="password" value="abuginsidemistycorner" />
    <property name="initialSize" value="100" />
    <property name="minEvictableIdleTimeMillis" value="30000" />
    <property name="timeBetweenEvictionRunsMillis" value="60000" />
    <property name="maxIdle" value="20" />
</bean>

Make sure that the placeholder names match your variables you have setup.

Upvotes: 51

MPavesi
MPavesi

Reputation: 971

If you are using the class org.springframework.beans.factory.config.PropertyPlaceholderConfigurer to load the property files, you can set the property systemPropertiesMode to the value SYSTEM_PROPERTIES_MODE_OVERRIDE.

In the spring.xml you'll have this bean:

<bean id="propertyPlaceholder"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="locations">
        <list>
            <value>classpath://file.properties</value>                  
        </list>
    </property>
</bean>

Spring will load the system properties in this way:

Check system properties first, before trying the specified properties. This allows system properties to override any other property source.

In this way you should be able to read the system properties as normal properties.

Upvotes: 9

Tomasz Janisiewicz
Tomasz Janisiewicz

Reputation: 649

For someone who use JavaConfig:

In @Configuration file we need to have:

@Bean 
public static PropertyPlaceholderConfigurer properties() {

    PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
    ClassPathResource[] resources = new ClassPathResource[ ] {
        new ClassPathResource("db.properties")
    };
    ppc.setLocations( resources );
    ppc.setIgnoreUnresolvablePlaceholders( true );
    ppc.setSearchSystemEnvironment(true);
    return ppc;
}

@Value("${db.url}")
private String dbUrl; 
@Value("${db.driver}")
private String dbDriver;
@Value("${db.username}")
private String dbUsername;
@Value("${db.password}")
private String dbPassword;

@Bean
public DataSource db() {

    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setUrl(dbUrl);
    dataSource.setDriverClassName(dbDriver);
    dataSource.setUsername(dbUsername);
    dataSource.setPassword(dbPassword);
    return dataSource;
}

important is line: ppc.setSearchSystemEnvironment(true);

after that in db.properties, I have:

db.url = ${PG_URL}
db.driver = ${PG_DRIVER}
db.username = ${PG_USERNAME}
db.password = ${PG_PASSWORD}

Upvotes: 5

Related Questions