Loading...

March 5, 2009

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

We look into the Spring Configurator a bit more, because we have not seen all of the possibilities. If we read the previous parts (part 1, part 2, part 3, part 4) we already experienced the power of the Spring Configurator. In this part we learn how to add our own properties to the configurator.

It is a good idea to extract settings from the Java code and externalize into a configuration file. This configuration file can be a Java properties file. In the application we can load the properties files and use the property values in our code. This mechanism is very easy to implement with the Spring Configurator. The only thing we need to do is place the Java properties file at a certain location and inject the Spring Configurator settings object in our application. Every property in the properties file is then available via the Spring Configurator.

Let's see how this works with our example. First we create a new property file at src/main/resources/META-INF/cocoon/properties/settings.properties and define the property machine:

machine=My muscle machine

We change our Sample class so we can display the value of this property (see lines 28-30):

package com.mrhaki.netbeans.mavenapp;

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

@Component
public class Sample {

    private Settings settings;

    private String text;

    private int timeout = 1000;

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

    public void setText(String name) {
        this.text = name;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public String getMachine() {
        return settings.getProperty("machine");
    }
    
    @Override
    public String toString() {
        return "Running in [" + settings.getRunningMode() + "] mode. "
                + "Text = [" + text + "] and timeout = [" + timeout + "].";
    }
}

The Settings class has two methods to get properties:

  • getProperty(String propertyName) to get the value for the property with propertyName
  • getProperty(String propertyName, String defaultValue) to get the value for the property and if it is not found use a default value
This way we can get the value for all available properties.

To test if we really get the value for our property we change our test class to output the property value:

package com.mrhaki.netbeans.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) {
        super(testName);
    }

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

    public void testApp() {
        final ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println(((Sample)appContext.getBean("sample")).getMachine());
    }
}

If we run the test (mvn test) we get the following output:

Muscle machine

But wait that is not all. If we use the Settings object we also have access to the standard Java system properties and environment variables. The Java system properties can be accessed with their property name. The environment variables are prefixed with env.:

System.out.println(settings.getProperty("os.name"); // Output: Windows Vista
System.out.println(settings.getProperty("env.PROMPT"); // Output: $p$g

In this part we have learned how to access our own defined properties, Java system properties and environment variables.