February 17, 2009

Use Spring Configurator to support different dev, test and production environments with Spring configuration files (Part 1)

We develop an application usually on a development environment: our computer. Then the application gets deployed to a test environment to be tested by users. And finally we deploy the application to the production environment so the application is live. This scenario is the most simple one and can of course be more complicated with extra environments for integration testing or other things.

The Spring configuration files are usually different for each of the environments. For example we can define a database JDBC URL in the Spring configuration files for a development database, but that is different from the database JDBC URL in the production enviroment. Spring provides some kind of support with PropertyPlaceHolderConfigurer and PropertyOverrideConfigurer to define properties. But the Spring Configurator provides transparent support for Spring configuration in different environments or running modes.

Let's start with a simple example to get the Spring Configurator working. We create a new Maven project with the QuickStart archetype (mvn archetype:generate, choose the QuickStart archetype, groupId is com.mrhaki.spring.mavenapp and artifactId is springconfapp). We add the Spring configurator to the pom.xml dependencies section:


Next we add a basic Spring configuration file to the src/main/resources directory with the name applicationContext.xml and the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
           http://cocoon.apache.org/schema/configurator http://cocoon.apache.org/schema/configurator/cocoon-configurator-1.0.1.xsd">

    <context:component-scan base-package="com.mrhaki.spring.mavenapp"/>

Notice at line 11 we set-up Spring to autodetect components in the com.mrhaki.spring.mavenapp package. And in line 12 we create the Spring Configurator settings object. We create a new Java class Sample in the com.mrhaki.spring.mavenapp package:

package com.mrhaki.spring.mavenapp;

import org.apache.cocoon.configuration.Settings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

public class Sample {

    private Settings settings;

    public void setSettings(Settings settings) {
        this.settings = settings;

    public String toString() {
        return "Running in [" + settings.getRunningMode() + "] mode.";

For the example we add the Spring Configurator settings object as a property to the Sample class. In the toString() method we return the current environment that is used. Now we change the AppTest class and use our Sample class and display which running mode is used:

package com.mrhaki.spring.mavenapp;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest extends TestCase {

    public AppTest(String testName) {

    public static Test suite() {
        return new TestSuite(AppTest.class);

    public void testApp() {
        final ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");

Now if we run the test (mvn test) we get the following output:

Running in [prod] mode.

The prod running mode is the default running mode for the Spring Configurator if we don't do anything else. We can change the running mode by using the environment property org.apache.cocoon.mode. For example if we run the test again, but now use mvn test -Dorg.apache.cocoon.mode=dev we get the following output:

Running in [dev] mode.

This way we can easily change the running mode to be used. This is part 1 of the Spring Configurator. In the next part we will see how we can define and use properties for different environments.