Skip to content
Home » PropertyPlaceHolderConfigurer example

PropertyPlaceHolderConfigurer example

  • by
PropertyPlaceHolderConfigurer example

1. Overview

In this article, we will discuss the PropertyPlaceHolderConfigurer example.

2. BeanFactoryPostProcessor

A bean factory post-processor is a java class that implements the org.springframework.beans.factory.config.BeanFactoryPostProcessor interface. Based on the Spring container type, you must execute manually:

  1. BeanFactory – Manual
  2. ApplicationContext – Automatic.

To know the differences between BeanFactory and ApplicationContext, see this article.

The Bean factory post-processors enable you to apply changes to the BeanFactory or ApplicationContext after its construction.

Spring includes several pre-existing bean factory post-processors, such as:

  1. PropertyResourceConfigurer 
  2. PropertyPlaceHolderConfigurer
  3. BeanNameAutoProxyCreator – useful for wrapping other beans transactionally or with any other kind of proxy.

You can also implement the BeanFactoryPostProcessor interface and create custom bean factory post-processors.

As mentioned earlier, you must manually apply the BeanFactoryPostProcessor in case of BeanFactory. For example, the following code applies the PropertyPlaceholderConfigurer manually.

BeanDefinitionRegistry beanDefinitionRegistry = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanDefinitionRegistry);
reader.loadBeanDefinitions(new ClassPathResource("config.xml"));

PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new ClassPathResource("jdbc.properties"));

cfg.postProcessBeanFactory(beanDefinitionRegistry);

However, an ApplicationContext will detect any beans which are deployed into it which implement the BeanFactoryPostProcessor interface, and automatically use them as bean factory post-processors.

Nothing else needs to be done other than deploying these post-processor in a similar fashion to any other bean.

Since this manual step is not convenient, and ApplictionContexts are functionally supersets of BeanFactories, it is generally recommended that ApplicationContext variants are used when bean factory post-processors are needed.

2.1. PropertyPlaceholderConfigurer example

The PropertyPlaceholderConfigurer, implemented as a bean factory post-processor, is used to externalize some property values from a BeanFactory definition, into another separate file in Java Properties format.

This is useful to allow the person deploying an application to customize some key properties (for example database URLs, usernames and passwords), without the complexity or risk of modifying the main XML definition file or files for the BeanFactory.

Assume a Bean definition where a DataSource with placeholder values is defined:

For example, we defined a data source, and configured some properties from an external Properties file.

At runtime, we will apply a PropertyPlaceholderConfigurer to the BeanFactory which will replace some properties of the datasource:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="${jdbc.driverClassName}"/>
  <property name="url" value="${jdbc.url}"/>
  <property name="username" value="${jdbc.username}"/>
  <property name="password" value="${jdbc.password}"/>
</bean>

The actual values come from another file in Properties format:

jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root

To use this with a BeanFactory, you need to execute the bean factory post-processor manually:

BeanDefinitionRegistry beanDefinitionRegistry = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanDefinitionRegistry);
reader.loadBeanDefinitions(new ClassPathResource("config.xml"));

PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new ClassPathResource("jdbc.properties"));

cfg.postProcessBeanFactory(beanDefinitionRegistry);
Note that ApplicationContexts can automatically recognize and apply beans deployed in them which implement BeanFactoryPostProcessor. 

The PropertyPlaceHolderConfigurer looks not only for properties in the Properties file you specify but also checks against the Java System properties if it cannot find a property you are trying to use.

We can customize this behavior by setting the systemPropertiesMode property of the configure.

  1. SYSTEM_PROPERTIES_MODE_OVERRID – always override
  2. SYSTEM_PROPERTIES_MODE_NEVER – never override
  3. SYSTEM_PROPERTIES_MODE_FALLBACK – override only if the property not found in the specified properties file
cfg.setSystemPropertiesMode(PropertyPlaceHolderConfigurer.SYSTEM_PROPERTIES_MODE_NEVER);

3. Conclusion

To sum up, we have learned the PropertyPlaceHolderConfigurer with an example. You can refer to our GitHub repository for code samples.

Leave a Reply

Your email address will not be published. Required fields are marked *