Mastering Custom Type Converters for Spring Boot @ConfigurationProperties
Learn how to create and register custom type converters for Spring Boot @ConfigurationProperties, enabling seamless binding of complex objects from property files using @ConfigurationPropertiesBinding and BeanFactoryPostProcessor techniques, including code examples, configuration snippets, and two registration approaches for practical implementation.
Environment: Spring Boot 3.2.5
1. Introduction
@ConfigurationProperties is a Spring Boot annotation that binds properties from configuration files (application.properties or application.yml) to a Java bean, simplifying type‑safe injection. It is usually used together with @Component or @Configuration and a prefix to map properties.
Spring automatically converts common types (List, Integer, Date, etc.) but for custom types you need to implement a converter.
@ConfigurationProperties(prefix = "pack.properties")
public class ConfigurationPropertiesBindingBean {
private String title;
private String name;
private PackObject object;
// getters, setters
}
public class PackObject {
private Integer age;
private String name;
// getters, setters
}Configuration file example:
pack:
properties:
title: ConfigurationPropertiesBinding
name: Properties Config
object: 20,PackThe object value is a comma‑separated string that should be converted to a custom PackObject. Spring does not know how, so a custom converter is required.
2. Practical Example
2.1 Custom Type Converter
public class StringToPackObject implements Converter<String, PackObject> {
@Override
public PackObject convert(String source) {
if (!StringUtils.hasLength(source)) {
return null;
}
String[] values = source.split(",");
if (values.length == 1) {
return null;
}
PackObject obj = new PackObject();
obj.setAge(Integer.valueOf(values[0]));
obj.setName(values[1]);
return obj;
}
}Spring discovers converters by implementing the Converter interface, or you can implement ConverterFactory for more flexibility.
public class StringToPackObjectFactory implements ConverterFactory<String, PackObject> {
@Override
public <T extends PackObject> Converter<String, T> getConverter(Class<T> targetType) {
// TODO
}
}To register the converter you can use a BeanFactoryPostProcessor:
public class PackConverterBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
ConversionService conversionService = beanFactory.getConversionService();
if (conversionService instanceof ConfigurableConversionService ccs) {
ccs.addConverter(new StringToPackObject());
}
}
}After registration, a simple application can inject the bound bean:
public class App implements CommandLineRunner {
@Resource
private ConfigurationPropertiesBindingBean bean;
@Override
public void run(String... args) throws Exception {
System.err.println(bean);
}
}Output example:
xxxBean [title=xxxooo, name=admin, object=PackObject [age=20, name=Pack]]Alternatively, you can register the converter as a bean annotated with @Component and @ConfigurationPropertiesBinding:
@Component
@ConfigurationPropertiesBinding
public class StringToPackObject implements Converter<String, PackObject> {
// ... implementation ...
}The @ConfigurationPropertiesBinding annotation works like a qualified bean name, allowing Spring to automatically pick up all Converter beans during property binding.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
