Last active
December 22, 2015 17:19
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
db.host=127.0.0.1 | |
db.port=27017 | |
db.name=partitionmagick |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
db.host=skadi.bluejeansnet.com |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# production mode | |
java -jar start.jar |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# development mode | |
java -Denv=dev -jar start.jar |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
Eclipse WTP settings:
- Double-click Server instance
- Click Open launch configuration
- Go to Arguments tab
- Append
-Denv=dev
to VM Arguments - OK
- Save
What if a configuration item is not of String type, e.g. an enum?
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
I know databases connections can be made infinitely portable by removing them entirely from code and configuring them using a JNDI definition in the servlet container's XML. This is a more lightweight solution that is well-suited to simple parameters, such as "the SOAP client should not verify SSL certificates in development mode, because no development server is going to have a valid cert." Plus, who uses Mongo with JNDI, seriously.