Spring Property Prefix Filtering: 3 Proven Methods to Access Prefixed Properties

Spring Property Prefix Filtering

Last updated: April 24, 2025

Working with Spring applications often involves managing numerous configuration properties across multiple files. A common challenge developers face is how to efficiently filter and access properties that share a common prefix. If you’ve ever found yourself repeatedly writing ${abc.hibernate.property} for dozens of properties, this guide is for you.

Spring property prefix filtering allows you to extract all properties with a specific prefix without manually referencing each one. This technique can significantly reduce XML bloat and make your configuration more maintainable.

Table of Contents

Understanding the Property Prefix Challenge

In Spring applications, we often use PropertyPlaceholderConfigurer to load property files:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>a.properties</value>
            <value>b.properties</value>
            <value>c.properties</value>
        </list>
    </property>
</bean>

These property files might contain numerous entries with a common prefix:

abc.hibernate.show_sql=true
abc.hibernate.default_schema=myschema
abc.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
abc.hibernate.format_sql=true
abc.hibernate.hbm2ddl.auto=validate

When configuring beans that need these properties (like a Hibernate SessionFactory), you would typically need to reference each property individually:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="hibernateProperties">
        <util:properties>
            <prop key="hibernate.show_sql">${abc.hibernate.show_sql}</prop>
            <prop key="hibernate.default_schema">${abc.hibernate.default_schema}</prop>
            <prop key="hibernate.dialect">${abc.hibernate.dialect}</prop>
            <prop key="hibernate.format_sql">${abc.hibernate.format_sql}</prop>
            <prop key="hibernate.hbm2ddl.auto">${abc.hibernate.hbm2ddl.auto}</prop>
        </util:properties>
    </property>
</bean>

This approach is verbose and prone to errors. Let’s explore three better solutions for Spring property prefix filtering.

Spring property prefix filtering simplifies configuration management by automatically extracting properties with common prefixes

Method 1: Creating a Custom PrefixedProperties Class

The first approach involves creating a custom class that extends java.util.Properties to filter properties by prefix:

import java.util.Enumeration;
import java.util.Properties;

public class PrefixedProperties extends Properties {
    public PrefixedProperties(Properties props, String prefix) {
        if (props == null) {
            return;
        }

        Enumeration<String> en = (Enumeration<String>) props.propertyNames();
        while (en.hasMoreElements()) {
            String propName = en.nextElement();
            String propValue = props.getProperty(propName);

            if (propName.startsWith(prefix)) {
                String key = propName.substring(prefix.length());
                setProperty(key, propValue);
            }
        }
    }
}

To use this class in your Spring configuration:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="hibernateProperties">
        <bean class="com.example.PrefixedProperties">
            <constructor-arg ref="props"/> <!-- reference to all properties -->
            <constructor-arg value="abc.hibernate."/> <!-- prefix -->
        </bean>
    </property>
</bean>

This approach requires you to make your properties available as a bean, which you can do using PropertiesFactoryBean or Spring’s utility namespace.

Method 2: Using Reflection to Access PropertyPlaceholderConfigurer

Another approach leverages reflection to access and filter the properties loaded by PropertyPlaceholderConfigurer:

public static Properties filterProperties(String prefix, PropertyPlaceholderConfigurer ppc) {
    Properties props = new Properties();
    Method method = ReflectionUtils.findMethod(PropertiesLoaderSupport.class, "mergeProperties");
    ReflectionUtils.makeAccessible(method);
    Properties all = (Properties) ReflectionUtils.invokeMethod(method, ppc);

    for (String key : all.stringPropertyNames()) {
        if (key.startsWith(prefix))
            props.setProperty(key.substring(prefix.length()), all.getProperty(key));
    }

    return props;
}

This can be used with Spring’s SpEL (Spring Expression Language):

<bean id="ppc" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <!-- configuration -->
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="hibernateProperties" value="#{T(com.example.PropertyUtils).filterProperties('abc.hibernate.', @ppc)}" />
</bean>

Method 3: Implementing a Custom PropertiesFactoryBean

The third approach creates a custom FactoryBean that loads and filters properties:

public class PrefixedPropertyFactoryBean extends AbstractFactoryBean<Properties> {

    private List<Resource> locations;
    public void setLocations(List<Resource> locations) { this.locations = locations; }

    private String prefix;
    public void setPrefix(String prefix) { this.prefix = prefix; }

    @Override 
    public Class<?> getObjectType() { return Properties.class; }

    @Override
    protected Properties createInstance() throws Exception {
        Properties properties = new Properties();
        for (Resource resource : locations) {
           properties.load(resource.getInputStream());
        }
        
        Properties filteredProps = new Properties();
        for (String key : properties.stringPropertyNames()) {
            if (key.startsWith(prefix)) {
                filteredProps.setProperty(key.substring(prefix.length()), properties.getProperty(key));
            }
        }
        
        return filteredProps;
    }
}

You can use this factory bean in your Spring configuration:

<bean id="hibernateProps" class="com.example.PrefixedPropertyFactoryBean">
    <property name="locations">
        <list>
            <value>classpath:a.properties</value>
            <value>classpath:b.properties</value>
            <value>classpath:c.properties</value>
        </list>
    </property>
    <property name="prefix" value="abc.hibernate." />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="hibernateProperties" ref="hibernateProps" />
</bean>

Comparing the Different Approaches

Each Spring property prefix filtering method has its advantages:

  1. Custom PrefixedProperties Class: Simple to implement but requires properties to be exposed as a bean.
  2. Reflection Method: Directly accesses properties from PropertyPlaceholderConfigurer but relies on internal Spring APIs that could change.
  3. Custom PropertiesFactoryBean: Most flexible but requires loading properties again, potentially duplicating work.

The best approach depends on your specific requirements and constraints.

Best Practices for Property Management

Regardless of which method you choose, consider these best practices for managing prefixed properties in Spring:

  • Use consistent prefix naming conventions across your application
  • Document the purpose of each prefix in your codebase
  • Consider using Spring Boot’s relaxed binding for more modern applications
  • For complex property structures, consider switching to YAML format which supports hierarchical configurations

Conclusion

Spring property prefix filtering techniques can significantly reduce configuration boilerplate and improve the maintainability of your Spring applications. The three methods outlined here provide flexible options for different scenarios, allowing you to choose the approach that best fits your needs.

By implementing one of these solutions, you can eliminate repetitive property references and make your Spring configuration more concise and easier to maintain.

Have you implemented any of these approaches in your Spring applications? Or do you have another method for handling prefixed properties? Share your experience in the comments below!


If you found this guide helpful, check out our other Spring tutorials:

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

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