<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;A0UCSHw_fip7ImA9WhRRFE4.&quot;"><id>tag:blogger.com,1999:blog-4210742358358282564</id><updated>2011-11-27T16:14:29.246-08:00</updated><category term="springframework" /><category term="java" /><title>tastybyte</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://tastybyte.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://tastybyte.blogspot.com/" /><author><name>Lars</name><uri>http://www.blogger.com/profile/01250360266472369504</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/tastybyte" /><feedburner:info uri="tastybyte" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CEEFRnszeyp7ImA9WB5TFEQ.&quot;"><id>tag:blogger.com,1999:blog-4210742358358282564.post-776751735453612155</id><published>2007-05-29T19:11:00.000-07:00</published><updated>2007-05-29T19:36:57.583-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-05-29T19:36:57.583-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="springframework" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><title>Environment-specific config with Spring</title><content type="html">&lt;h1&gt;The Problem&lt;/h1&gt;&lt;br /&gt;After a jaunt working with Rails I'm back in Java-land.  Now that I've tasted the sweet simplicity I'm jonesin' to feed it back into my Java projects.&lt;br /&gt;&lt;br /&gt;So here's a little hack that let me apply my Rails idiom of environment/[development|test|production] to the Java world.&lt;br /&gt;&lt;h1&gt;The Implementation&lt;/h1&gt;&lt;h3&gt;The config files&lt;/h3&gt;&lt;i&gt;development.properties&lt;/i&gt;:&lt;br /&gt;&lt;pre&gt;jdbc.driverClassName=oracle.jdbc.OracleDriver&lt;br /&gt;jdbc.url=jdbc:oracle:thin:@...&lt;br /&gt;&lt;br /&gt;hibernate.dialect=org.hibernate.dialect.OracleDialect&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;i&gt;test.properties&lt;/i&gt;:&lt;br /&gt;&lt;pre&gt;jdbc.driverClassName=org.hsqldb.jdbcDriver&lt;br /&gt;jdbc.url=jdbc:hsqldb:mem:unittest&lt;br /&gt;jdbc.username=sa&lt;br /&gt;jdbc.password=&lt;br /&gt;&lt;br /&gt;hibernate.dialect=org.hibernate.dialect.HSQLDialect&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;Same deal with production.properties&lt;/i&gt;&lt;br /&gt;&lt;h3&gt;Creating the ApplicationContext&lt;/h3&gt;It's not a web-app so I'm doing it programatically.&lt;br /&gt;&lt;pre&gt;beanFactory = new ClassPathXmlApplicationContext(new String[] {"beans.xml"}, false);&lt;br /&gt;&lt;br /&gt;PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();&lt;br /&gt;configurer.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE);&lt;br /&gt;&lt;br /&gt;String environment = System.getProperty("environment", "development");&lt;br /&gt;File customProperties = new File("/etc/conf/custom.properties");&lt;br /&gt;configurer.setLocations(new Resource[] {new ClassPathResource(environment + ".properties"), new FileSystemResource(customProperties)});&lt;br /&gt;&lt;br /&gt;beanFactory.addBeanFactoryPostProcessor(configurer);&lt;br /&gt;beanFactory.refresh();&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Unit tests&lt;/h3&gt;I also created a mini spring file &lt;i&gt;beans-test.xml&lt;/i&gt;:&lt;br /&gt;&lt;pre&gt;&amp;lt;beans&amp;gt;&lt;br /&gt;&amp;lt;bean class=\&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer\&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;property name=\&amp;quot;locations\&amp;quot;&amp;gt;&lt;br /&gt; &amp;lt;value&amp;gt;classpath:test.properties&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;/pre&gt;All it does is load in my test.properties.&lt;br /&gt;&lt;h5&gt;My test superclass&lt;/h5&gt;&lt;pre&gt;import org.springframework.test.AbstractDependencyInjectionSpringContextTests;&lt;br /&gt;&lt;br /&gt;public abstract class TestSupport extends AbstractDependencyInjectionSpringContextTests {&lt;br /&gt;public AbstractMdsIntegrationTestSupport() {&lt;br /&gt;setPopulateProtectedVariables(true);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;protected String[] getConfigLocations() {&lt;br /&gt;return new String[] {"classpath:/beans-test.xml", "classpath:/beans.xml"};&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;h1&gt;Results&lt;/h1&gt;Now I can check out a clean codebase and run the unit tests and also fire up my application with the main() function, both from my IDE with no flag, properties file editing, etc.  Then I can switch to production mode with just a -Denvironment=production.&lt;br /&gt;&lt;br /&gt;You may have caught the &lt;i&gt;customProperties&lt;/i&gt; file, that's how I keep from having to wrangle my production passwords into the classpath or system properties.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4210742358358282564-776751735453612155?l=tastybyte.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/tastybyte/~4/YnuRDwpx1IY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://tastybyte.blogspot.com/feeds/776751735453612155/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4210742358358282564&amp;postID=776751735453612155" title="24 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4210742358358282564/posts/default/776751735453612155?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4210742358358282564/posts/default/776751735453612155?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/tastybyte/~3/YnuRDwpx1IY/environment-specific-config-with-spring.html" title="Environment-specific config with Spring" /><author><name>Lars</name><uri>http://www.blogger.com/profile/01250360266472369504</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>24</thr:total><feedburner:origLink>http://tastybyte.blogspot.com/2007/05/environment-specific-config-with-spring.html</feedburner:origLink></entry></feed>

