- 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.