Over a million developers have joined DZone.

A Custom Property in Spring

DZone 's Guide to

A Custom Property in Spring

· Java Zone ·
Free Resource

<context:property-placeholder> is a really easy way to provide property replacements in Spring configurations with values from a standard Java Properties file. But what if you don’t want a property hard coded into a file – a clear text password for instance? Spring provides all the bits and pieces to write your own property replacement. Let me introduce my CustomPropertyConfigurer.

I’ll demonstrate using a variation on the theme of the Spring JDBC Template. MyQuery is a simple extension of org.springframework.jdbc.core.JDBCTemplate that gets the current timestamp from a MySQL database. Here’s the, hopefully familiar, configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  <context:property-placeholder location="classpath:jdbc.properties" />
  <bean id="myQuery" class="rob.MyQuery">
    <property name="dataSource" ref="dataSource" />
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />

Except the jdbc.properties file does not contain the password:


I will set the jdbc.password property myself from what is entered on the command line.

public static void main(String... args) {
    char[] password = System.console().readPassword("Password: ");
    Properties properties = new Properties();
    properties.setProperty("jdbc.password", new String(password));
    ConfigurableApplicationContext context =
        new ClassPathXmlApplicationContext(
            new String[] {
            new CustomPropertyConfigurer(properties));
    MyQuery myQuery = context.getBean(MyQuery.class);

Where the CustomPropertyConfigurer is:

import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.StringValueResolver;
public class CustomPropertyConfigurer implements BeanFactoryPostProcessor {
    private final Properties properties;
    public CustomPropertyConfigurer(Properties properties) {
        this.properties = properties;
    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory beanFactoryToProcess)
    throws BeansException {
        BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(
                new BeanDirectoryResolver());
        String[] beanNames =
        for (int i = 0; i < beanNames.length; i++) {
            BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(
            try {
            catch (BeanDefinitionStoreException ex) {
                throw new BeanDefinitionStoreException(
                        bd.getResourceDescription(), beanNames[i],
    class BeanDirectoryResolver implements StringValueResolver {
        private final PropertyPlaceholderHelper helper;
        public BeanDirectoryResolver() {
            helper = new PropertyPlaceholderHelper("${", "}");
        public String resolveStringValue(String strVal) {
            return helper.replacePlaceholders(strVal, properties);

The CustomPropertyConfigurer gets applied first. It leaves any properties it can’t resolve (all but the password) for the standard <context:property-configurer> to resolve. Unit tests running against a different jdbc.propeties file can continue to provide the password as before.

Here it is running:

Cusom Propery Configurer Running

There are many other examples of configuration values that might only be discovered at runtime – file names, schedule dates, form values etc. So long as the value can be a String, a CustomPropertyConfigurer provides a simple way of passing these values to Spring.



Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}