Skip to content

Instantly share code, notes, and snippets.

@Aldaviva
Last active December 22, 2015 17:19
Show Gist options
  • Save Aldaviva/6505790 to your computer and use it in GitHub Desktop.
Save Aldaviva/6505790 to your computer and use it in GitHub Desktop.
How to use environment-specific configuration in Spring, activated with a Java system property: -Denv=dev
As a Java developer, I want to be able to inject configuration properties into my application as simply
and easily as possible. I want these properties to be different depending on which environment (prod
vs. stage vs. dev) the system is running in. I don't want to generate separate, non-portable build
artifacts for each environment, because they will get confused. I don't want to redefine property values
that are the same across different environments (dev should inherit and override prod, not duplicate
prod). I want the default environment to be prod, so any operations person can be completely oblivious to
this system and still get the correct behavior.
In this example, a servlet application connects to a Mongo database. We want the database hostname to be
different depending on the environment; on prod, Mongo is hosted locally, but in dev, Mongo is on a VM
and the servlet is run from a workstation IDE.
db.host=127.0.0.1
db.port=27017
db.name=partitionmagick
db.host=skadi.bluejeansnet.com
#!/bin/bash
# production mode
java -jar start.jar
#!/bin/bash
# development mode
java -Denv=dev -jar start.jar
package vc.bjn.partitionmagick.config;
import com.mongodb.Mongo;
import com.mongodb.MongoOptions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoFactoryBean;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@Configuration
@EnableMongoRepositories(basePackages = "vc.bjn.partitionmagick")
public class DatabaseConfig {
@Value("${db.host}") private String dbHost;
@Value("${db.port}") private int dbPort;
@Value("${db.name}") private String dbName;
@Bean public MongoFactoryBean mongoConnection() {
final MongoFactoryBean mongoFactoryBean = new MongoFactoryBean();
mongoFactoryBean.setHost(dbHost);
mongoFactoryBean.setPort(dbPort);
final MongoOptions mongoOptions = new MongoOptions();
mongoOptions.autoConnectRetry = true;
mongoOptions.j = true;
mongoFactoryBean.setMongoOptions(mongoOptions);
return mongoFactoryBean;
}
@Bean public MongoDbFactory mongoDbFactory(final Mongo mongoConnection) {
return new SimpleMongoDbFactory(mongoConnection, dbName);
}
@Bean public MongoTemplate mongoTemplate(final MongoDbFactory mongoDbFactory) {
return new MongoTemplate(mongoDbFactory);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- This is impossible in Spring JavaConfig because the list of filenames has a wildcard -->
<context:property-placeholder location="classpath*:META-INF/common/*.properties,classpath*:META-INF/prod/*.properties,classpath*:META-INF/${env}/*.properties" ignore-unresolvable="true" />
<!-- This file is not the primary entry point to Spring context configuration.
It is imported by AppConfig.java, which is loaded by web.xml -->
</beans>
@Aldaviva
Copy link
Author

Eclipse WTP settings:

  1. Double-click Server instance
  2. Click Open launch configuration
  3. Go to Arguments tab
  4. Append -Denv=dev to VM Arguments
  5. OK
  6. Save

@greenlaw110
Copy link

What if a configuration item is not of String type, e.g. an enum?

@greenlaw110
Copy link

For some context (prod) we need to set mongo db username/password, and for others dev/test, we do not need them. How to handle this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment