Close

Spring - Using BeanWrapper

[Last Updated: Dec 22, 2023]

Spring beans creation and manipulation is based on standard JavaBeans. The package org.springframework.beans contains interfaces and classes for manipulating beans.

In this tutorial we are going to quickly walk through important interfaces/classes.




BeanWrapper interface

Spring's BeanWrapper is central interface of JavaBeans infrastructure.


BeanWrapper extends various interfaces. In this tutorial we will focus on PropertyAccessor interface which provides methods to get and set property values, get property descriptors, and query the readability/writability of properties. It also supports setting of index properties.

Definition of BeanWrapper

(Version: spring-framework 6.1.2)
package org.springframework.beans;
   ........
public interface BeanWrapper extends ConfigurablePropertyAccessor {
    .............
    Object getWrappedInstance(); 1
    Class<?> getWrappedClass(); 2
    PropertyDescriptor[] getPropertyDescriptors(); 3
    PropertyDescriptor getPropertyDescriptor(String propertyName)
            throws InvalidPropertyException; 4
}
1Return the bean instance wrapped by this object.
2Return the type of the wrapped bean instance.
3Obtain the PropertyDescriptors for the wrapped object (as determined by standard JavaBeans introspection).
4Obtain the property descriptor for a specific property of the wrapped object.

Definition of PropertyAccessor

(Version: spring-framework 6.1.2)
package org.springframework.beans;
   ........
public interface PropertyAccessor {
    .............
    boolean isReadableProperty(String propertyName); 1
    boolean isWritableProperty(String propertyName); 2
    @Nullable
    Class<?> getPropertyType(String propertyName) throws BeansException; 3
    @Nullable
    TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException; 4
    @Nullable
    Object getPropertyValue(String propertyName) throws BeansException; 5
    void setPropertyValue(String propertyName, @Nullable Object value)
            throws BeansException; 6
    void setPropertyValue(PropertyValue pv) throws BeansException; 7
    void setPropertyValues(Map<?, ?> map) throws BeansException; 8
    void setPropertyValues(PropertyValues pvs) throws BeansException; 9
    void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown)
            throws BeansException; 10
    void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
            throws BeansException; 11
}
1Determine whether the specified property is readable.
2Determine whether the specified property is writable.
3Determine the property type for the specified property
4Return a type descriptor for the specified property
5Get the current value of the specified property
6Set the specified value as current property value.
7Set the specified value as current property value. PropertyValue holds the value for an individual bean property. We can set property via constructor PropertyValue(String name, Object value)
8Perform a batch update from a Map.
9Perform a batch update from a PropertyValues.
PropertyValues is an interface. We can use it's implementation MutablePropertyValues which has methods like add(String propertyName, Object propertyValue), addPropertyValue(PropertyValue pv) etc.
10Perform a batch update with more control over behavior.
11Perform a batch update with full control over behavior.

Implementations of BeanWrapper/ConfigurablePropertyAccessor

BeanWrapperImpl is implementation of BeanWrapper.
DirectFieldAccessor is another concrete class which implements ConfigurablePropertyAccessor. This class is used to set field values directly.

PropertyAccessorFactory class

PropertyAccessorFactory is another way to get BeanWrapper/DirectFieldAccessor instances. It's based on factory pattern so we don't have to worry about what implementation to use.

Following methods of PropertyAccessorFactory can be used:

public static BeanWrapper forBeanPropertyAccess(Object target)
public static ConfigurablePropertyAccessor forDirectFieldAccess(Object target)

Examples

A bean

package com.logicbig.example;

class Person {
  private String name;
  private int age;

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  public int getAge() {
      return age;
  }

  public void setAge(int age) {
      this.age = age;
  }

  @Override
  public String toString() {
      return "Person{" +
              "name='" + name + '\'' +
              ", age=" + age +
              '}';
  }
}

Using setPropertyValue(String propertyName, Object value)

package com.logicbig.example;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.PropertyValue;

public class BeanWrapperExample {
    public static void main (String[] args) {
        BeanWrapper beanWrapper = new BeanWrapperImpl(new Person());
        beanWrapper.setPropertyValue("name", "John");
        beanWrapper.setPropertyValue("age", 33);
       //the next commented line will also work, auto conversion is performed by Spring
        /*   beanWrapper.setPropertyValue("age", "33");*/

        System.out.println("bean: "+beanWrapper.getWrappedInstance());
        //getting property value
        Object value = beanWrapper.getPropertyValue("name");
        System.out.println("person.name: "+value);
    }
}

Output

bean: Person{name='John', age=33}
person.name: John

Using setPropertyValue(PropertyValue pv)

package com.logicbig.example;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.PropertyValue;

public class BeanWrapperPropertyValueExample {
    public static void main (String[] args) {
        BeanWrapper beanWrapper = new BeanWrapperImpl(new Person());
        PropertyValue pv = new PropertyValue("name", "John");
        beanWrapper.setPropertyValue("name", "John");
        PropertyValue pv2 = new PropertyValue("age", 33);
        beanWrapper.setPropertyValue(pv);
        beanWrapper.setPropertyValue(pv2);
        System.out.println("bean: "+beanWrapper.getWrappedInstance());
    }
}

Output

bean: Person{name='John', age=33}

Using setPropertyValues(Map<?, ?> map)

package com.logicbig.example;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.util.HashMap;
import java.util.Map;

public class BeanWrapperMapExample {
    public static void main (String[] args) {
        BeanWrapper beanWrapper = new BeanWrapperImpl(new Person());
        Map<String, Object> map = new HashMap<>();
        map.put("name", "Tina");
        map.put("age", "32");
        beanWrapper.setPropertyValues(map);
        System.out.println(beanWrapper.getWrappedInstance());
    }
}

Output

Person{name='Tina', age=32}

Using setPropertyValues(PropertyValues pvs)

package com.logicbig.example;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.MutablePropertyValues;

public class BeanWrapperMutablePropertyExample {
    public static void main (String[] args) {
        BeanWrapper bw = new BeanWrapperImpl(new Person());
        MutablePropertyValues mpv = new MutablePropertyValues();
        mpv.add("name", "Diana");
        mpv.add("age", "30");

        bw.setPropertyValues(mpv);
        System.out.println(bw.getWrappedInstance());
    }
}

Output

Person{name='Diana', age=30}

Using isReadableProperty(String propertyName)

package com.logicbig.example;

import java.util.Date;

public class TestBean {
  private String aString;
  private int anInt = 5;
  private Date date = new Date(12000000000L);

  public String getAString () {
      return aString;
  }

  public void setAString (String aString) {
      this.aString = aString;
  }

  public int getAnInt () {
      return anInt;
  }

  public void setAnInt (int anInt) {
      this.anInt = anInt;
  }

  @Override
  public String toString() {
      return "TestBean{" +
              "aString='" + aString + '\'' +
              ", anInt=" + anInt +
              ", date=" + date +
              '}';
  }
}
package com.logicbig.example;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class BeanWrapperReadOnlyCheckExample {
    public static void main (String[] args) {
        BeanWrapper bw = new BeanWrapperImpl(new TestBean());
        bw.setPropertyValue("aString", "someString");
        System.out.println("date read only: " + bw.isReadableProperty("date"));
        //similarly we have bw.isWritableProperty(..) method
        System.out.println(bw.getWrappedInstance());
    }
}

Output

date read only: false
TestBean{aString='someString', anInt=5, date=Tue May 19 16:20:00 CDT 1970}

Using PropertyAccessorFactory

package com.logicbig.example;

import com.logicbig.example.TestBean;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;

public class PropertyAccessorFactoryExample {

    public static void main (String[] args) {
        BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(new Person());
        bw.setPropertyValue("name", "Raj");
        bw.setPropertyValue("age", "26");
        System.out.println(bw.getWrappedInstance());
    }
}

Output

Person{name='Raj', age=26}

Example Project

Dependencies and Technologies Used:

  • spring-context 6.1.2 (Spring Context)
     Version Compatibility: 3.2.3.RELEASE - 6.1.2Version List
    ×

    Version compatibilities of spring-context with this example:

    • 3.2.3.RELEASE
    • 3.2.4.RELEASE
    • 3.2.5.RELEASE
    • 3.2.6.RELEASE
    • 3.2.7.RELEASE
    • 3.2.8.RELEASE
    • 3.2.9.RELEASE
    • 3.2.10.RELEASE
    • 3.2.11.RELEASE
    • 3.2.12.RELEASE
    • 3.2.13.RELEASE
    • 3.2.14.RELEASE
    • 3.2.15.RELEASE
    • 3.2.16.RELEASE
    • 3.2.17.RELEASE
    • 3.2.18.RELEASE
    • 4.0.0.RELEASE
    • 4.0.1.RELEASE
    • 4.0.2.RELEASE
    • 4.0.3.RELEASE
    • 4.0.4.RELEASE
    • 4.0.5.RELEASE
    • 4.0.6.RELEASE
    • 4.0.7.RELEASE
    • 4.0.8.RELEASE
    • 4.0.9.RELEASE
    • 4.1.0.RELEASE
    • 4.1.1.RELEASE
    • 4.1.2.RELEASE
    • 4.1.3.RELEASE
    • 4.1.4.RELEASE
    • 4.1.5.RELEASE
    • 4.1.6.RELEASE
    • 4.1.7.RELEASE
    • 4.1.8.RELEASE
    • 4.1.9.RELEASE
    • 4.2.0.RELEASE
    • 4.2.1.RELEASE
    • 4.2.2.RELEASE
    • 4.2.3.RELEASE
    • 4.2.4.RELEASE
    • 4.2.5.RELEASE
    • 4.2.6.RELEASE
    • 4.2.7.RELEASE
    • 4.2.8.RELEASE
    • 4.2.9.RELEASE
    • 4.3.0.RELEASE
    • 4.3.1.RELEASE
    • 4.3.2.RELEASE
    • 4.3.3.RELEASE
    • 4.3.4.RELEASE
    • 4.3.5.RELEASE
    • 4.3.6.RELEASE
    • 4.3.7.RELEASE
    • 4.3.8.RELEASE
    • 4.3.9.RELEASE
    • 4.3.10.RELEASE
    • 4.3.11.RELEASE
    • 4.3.12.RELEASE
    • 4.3.13.RELEASE
    • 4.3.14.RELEASE
    • 4.3.15.RELEASE
    • 4.3.16.RELEASE
    • 4.3.17.RELEASE
    • 4.3.18.RELEASE
    • 4.3.19.RELEASE
    • 4.3.20.RELEASE
    • 4.3.21.RELEASE
    • 4.3.22.RELEASE
    • 4.3.23.RELEASE
    • 4.3.24.RELEASE
    • 4.3.25.RELEASE
    • 4.3.26.RELEASE
    • 4.3.27.RELEASE
    • 4.3.28.RELEASE
    • 4.3.29.RELEASE
    • 4.3.30.RELEASE
    • 5.0.0.RELEASE
    • 5.0.1.RELEASE
    • 5.0.2.RELEASE
    • 5.0.3.RELEASE
    • 5.0.4.RELEASE
    • 5.0.5.RELEASE
    • 5.0.6.RELEASE
    • 5.0.7.RELEASE
    • 5.0.8.RELEASE
    • 5.0.9.RELEASE
    • 5.0.10.RELEASE
    • 5.0.11.RELEASE
    • 5.0.12.RELEASE
    • 5.0.13.RELEASE
    • 5.0.14.RELEASE
    • 5.0.15.RELEASE
    • 5.0.16.RELEASE
    • 5.0.17.RELEASE
    • 5.0.18.RELEASE
    • 5.0.19.RELEASE
    • 5.0.20.RELEASE
    • 5.1.0.RELEASE
    • 5.1.1.RELEASE
    • 5.1.2.RELEASE
    • 5.1.3.RELEASE
    • 5.1.4.RELEASE
    • 5.1.5.RELEASE
    • 5.1.6.RELEASE
    • 5.1.7.RELEASE
    • 5.1.8.RELEASE
    • 5.1.9.RELEASE
    • 5.1.10.RELEASE
    • 5.1.11.RELEASE
    • 5.1.12.RELEASE
    • 5.1.13.RELEASE
    • 5.1.14.RELEASE
    • 5.1.15.RELEASE
    • 5.1.16.RELEASE
    • 5.1.17.RELEASE
    • 5.1.18.RELEASE
    • 5.1.19.RELEASE
    • 5.1.20.RELEASE
    • 5.2.0.RELEASE
    • 5.2.1.RELEASE
    • 5.2.2.RELEASE
    • 5.2.3.RELEASE
    • 5.2.4.RELEASE
    • 5.2.5.RELEASE
    • 5.2.6.RELEASE
    • 5.2.7.RELEASE
    • 5.2.8.RELEASE
    • 5.2.9.RELEASE
    • 5.2.10.RELEASE
    • 5.2.11.RELEASE
    • 5.2.12.RELEASE
    • 5.2.13.RELEASE
    • 5.2.14.RELEASE
    • 5.2.15.RELEASE
    • 5.2.16.RELEASE
    • 5.2.17.RELEASE
    • 5.2.18.RELEASE
    • 5.2.19.RELEASE
    • 5.2.20.RELEASE
    • 5.2.21.RELEASE
    • 5.2.22.RELEASE
    • 5.2.23.RELEASE
    • 5.2.24.RELEASE
    • 5.2.25.RELEASE
    • 5.3.0
    • 5.3.1
    • 5.3.2
    • 5.3.3
    • 5.3.4
    • 5.3.5
    • 5.3.6
    • 5.3.7
    • 5.3.8
    • 5.3.9
    • 5.3.10
    • 5.3.11
    • 5.3.12
    • 5.3.13
    • 5.3.14
    • 5.3.15
    • 5.3.16
    • 5.3.17
    • 5.3.18
    • 5.3.19
    • 5.3.20
    • 5.3.21
    • 5.3.22
    • 5.3.23
    • 5.3.24
    • 5.3.25
    • 5.3.26
    • 5.3.27
    • 5.3.28
    • 5.3.29
    • 5.3.30
    • 5.3.31
    • Compatible Java Version: 17+
    • 6.0.0
    • 6.0.1
    • 6.0.2
    • 6.0.3
    • 6.0.4
    • 6.0.5
    • 6.0.6
    • 6.0.7
    • 6.0.8
    • 6.0.9
    • 6.0.10
    • 6.0.11
    • 6.0.12
    • 6.0.13
    • 6.0.14
    • 6.0.15
    • 6.1.0
    • 6.1.1
    • 6.1.2

    Versions in green have been tested.

  • JDK 17
  • Maven 3.8.1

Spring - BeanWrapper examples Select All Download
  • spring-bean-wrapper-examples
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • BeanWrapperExample.java

    See Also