Spring PropertySourcesPlaceholderConfigurer Example -1

0
This article demonstrates an example of  Spring PropertySourcesPlaceholderConfigurer. My scenario is I want to have different URLs for authorizations based on my environment. I have the below environments as of now and for each environment I want to have different URLs.

  • test
  • prod
dev.authorize.url=http://localhost:8280/springdemmo/dev/authorize
test.authorize.url=http://localhost:8280/springdemmo/test/authorize
prod.authorize.url=http://localhost:8280/springdemmo/prod/authorize

Let us first deal with the simple case. TestAuthorizationBean is my test bean which has URL property. Since URL varies based on the environment, I want this property to be a placeholder, for example ${url.env}. The actual value of the place holder will be set as a system property. Here is my context file.

<beans>

    <bean id="springdemoAuthorization" class="springdemo.TestAuthorizationBean">

        <property name="url" value="${url_env}"/>

    </bean>

</beans>

My authorization bean TestAuthorizationBean

package springdemo;
public class TestAuthorizationBean {
    private String url;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

Now lets try in a test case to check whether we can get the URL based on the environment. Assuming my environment is test based, I set the url_env to http://localhost:8280/springdemmo/test/authorize in my system properties.

   
    public void testUrl() {
        String testUrl = "http://localhost:8280/springdemo/testAuthorize";
        System.setProperty("url_env", testUrl);
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/springdemo/testPropertConfig.xml");
        assertEquals(testUrl, context.getEnvironment().getProperty("url_env"));
        assertEquals(testUrl, ((TestAuthorizationBean) context.getBean("springdemoAuthorization")).getUrl());
    }

When I run it it, I get error:

junit.framework.ComparisonFailure: 
Expected :http://localhost:8280/springdemo/testAuthorize
Actual   :${url_env}

The spring environment, does have the url_env set properly as the below assert passes:

assertEquals(url, context.getEnvironment().getProperty("url_env"));

What went wrong? Environment had the property but someone should process the bean TestAuthorizationBean to replace the place holders. This is where  PropertySourcesPlaceholderConfigurer kicks in.

PropertySourcesPlaceholderConfigureris a BeanFactoryPostProcessor and modifies the application context’s bean definitions before they are instantiated and configures individual bean property values from a property resource.

We will now add PropertySourcesPlaceholderConfigurer bean to our context and rerun the test case.

<beans>

    <bean id="springdemoAuthorization" class="springdemo.TestAuthorizationBean">

        <property name="url" value="${url_env}"/>

    </bean>

    <bean id="propConfig" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>

</beans>

After the changed config, the test passes.

Now I have included prod env in the test case:

    public void testUrl() {
        String testUrl = "http://localhost:8280/springdemo/testAuthorize";
        System.setProperty("url_env", testUrl);
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/springdemo/testPropertConfig.xml");
        assertEquals(testUrl, context.getEnvironment().getProperty("url_env"));
        assertEquals(testUrl, ((TestAuthorizationBean) context.getBean("springdemoAuthorization")).getUrl());

        String prodUrl = "http://localhost:8280/springdemo/prodAuthorize"; 
        System.setProperty("url_env", prodUrl);
        context = new ClassPathXmlApplicationContext("/springdemo/testPropertConfig.xml");
        assertEquals(prodUrl, context.getEnvironment().getProperty("url_env"));
        assertEquals(prodUrl, ((TestAuthorizationBean) context.getBean("springdemoAuthorization")).getUrl());
    }

What did PropertySourcesPlaceholderConfigurer do?. Since it is a BeanFactoryPostProcessor, it got a chance to revisit the BeanDefinitions and and the properties and constructor argument values contained in them and resolve the found property place holders.

In my next article, I will explore the example further and see other possibilities.

Share.

Leave A Reply