Backend Development 9 min read

Mastering Spring BeanWrapper: Set, Get, and Convert Bean Properties Efficiently

This article introduces Spring's BeanWrapper, explains how to set and retrieve simple and nested properties, demonstrates indexed and key‑based access, covers automatic and custom type conversion using PropertyEditorSupport and Converter, and clarifies conversion priority and registration details for backend developers.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring BeanWrapper: Set, Get, and Convert Bean Properties Efficiently

Environment: Spring 6.1.2

1. Introduction

BeanWrapper interface and BeanWrapperImpl implementation are important in Spring. They allow setting and getting property values (individually or in bulk), retrieving property descriptors, checking readability/writability, supporting nested properties, adding PropertyChangeListeners and VetoableChangeListeners without modifying target classes, and handling indexed properties. BeanWrapper is usually used by DataBinder and BeanFactory rather than directly by application code.

2. Practical Examples

2.1 Setting and Getting Basic and Nested Properties

Properties are accessed via setPropertyValue and getPropertyValue . Common expression forms include:

name – maps to getName()/setName(...)

account.name – nested property

account[2] – indexed property (array, List, etc.)

account[companyname] – Map key access

Example classes:

<code>public class Company {
    private String name;
    private Employee employee;
    // getters and setters
}
public class Employee {
    private String name;
    private float salary;
    private String[] address = new String[2];
    private Map<String, String> account = new HashMap<>();
    // getters and setters
}
</code>

Manipulating these beans:

<code>BeanWrapper company = new BeanWrapperImpl(new Company());
// set simple property
company.setPropertyValue("name", "Pack Company Inc.");
// create employee and bind
Employee emp = new Employee();
BeanWrapper empWrapper = new BeanWrapperImpl(emp);
empWrapper.setPropertyValue("name", "张三");
empWrapper.setPropertyValue("salary", 66666.66f);
company.setPropertyValue("employee", empWrapper.getWrappedInstance());
// get nested property
Float salary = (Float) company.getPropertyValue("employee.salary");
System.out.println(salary);
System.out.println(company.getWrappedInstance());
</code>

Output:

<code>66666.66
Company[name=Pack Company Inc., employee=Employee[name=张三, salary=66666.66]]
</code>

2.2 Index Access

<code>Employee emp = new Employee();
BeanWrapper empWrapper = new BeanWrapperImpl(emp);
empWrapper.setPropertyValue("address[0]", "新疆");
empWrapper.setPropertyValue("address[1]", "重庆");
</code>

2.3 Key Access

<code>BeanWrapper empWrapper = new BeanWrapperImpl(Employee.class);
empWrapper.setPropertyValue("account[home]", "H0001");
empWrapper.setPropertyValue("account[work]", "W0001");
System.out.println(empWrapper.getWrappedInstance());
</code>

Output:

<code>Employee[name=null, salary=0.0, address=[null, null], account={work=W0001, home=H0001}]
</code>

2.4 Automatic Type Conversion

When a string is assigned to a property of type float , BeanWrapper automatically converts it:

<code>BeanWrapper empWrapper = new BeanWrapperImpl(Employee.class);
empWrapper.setPropertyValue("salary", "88888.88");
</code>

Spring loads all *Editor classes from org.springframework.beans.propertyeditors , e.g.,

<code>this.defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, true));
</code>

Default supported conversions are illustrated below:

2.5 Custom Type Conversion

Custom converters can be added via PropertyEditorSupport or Spring’s Converter interface.

Using PropertyEditorSupport :

<code>public class StringToUserEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(String text) {
        User user = new User();
        String[] infos = text.split(",");
        user.setAge(Integer.parseInt(infos[0]));
        user.setName(infos[1]);
        setValue(user);
    }
}
</code>

Register and use:

<code>BeanWrapper wrapper = new BeanWrapperImpl(Pack.class);
wrapper.registerCustomEditor(User.class, new StringToUserEditor());
wrapper.setPropertyValue("user", "23,张三");
System.out.println(wrapper.getWrappedInstance());
</code>

Output:

<code>Pack[user=User[age=23, name=张三]]
</code>

Using Spring’s Converter :

<code>public class StringToUserConvert implements Converter<String, User> {
    @Override
    public User convert(String source) {
        User user = new User();
        String[] infos = source.split(",");
        user.setAge(Integer.parseInt(infos[0]));
        user.setName(infos[1] + " -");
        return user;
    }
}
</code>

Configure a ConversionService and apply:

<code>BeanWrapper wrapper = new BeanWrapperImpl(Pack.class);
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToUserConvert());
wrapper.setConversionService(conversionService);
wrapper.setPropertyValue("user", "23,张三");
System.out.println(wrapper.getWrappedInstance());
</code>

Output:

<code>Pack[user=User[age=23, name=张三 -]]
</code>

2.6 Conversion Priority

If both a custom PropertyEditor and a Converter are registered, the PropertyEditor takes precedence, as shown by the following test:

<code>DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToUserConvert());
wrapper.setConversionService(conversionService);
wrapper.registerCustomEditor(User.class, new StringToUserEditor());
// result: Pack[user=User[age=23, name=张三]]
</code>

Spring determines the conversion order based on internal rules, illustrated below:

Note: If a matching XxxEditor exists in the same package as the target type, Spring can locate it automatically without explicit registration.

Testing without registering a converter still produces correct output, demonstrating the robustness of BeanWrapper’s conversion mechanism.

That concludes the article; hope it helps you work with Spring BeanWrapper more elegantly.

Javabackend developmentSpringType ConversionBeanWrapperPropertyEditor
Spring Full-Stack Practical Cases
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.