Spring 中的 BeanWrapper

BeanWrapper 是 Spring 框架中的一个接口,它提供了一种方式来设置和获取 JavaBean 的属性。JavaBean 是一种特殊的 Java 类,遵循特定的编码约定(例如,私有属性和公共的 getter/setter 方法),通常用于封装数据

主要功能

1.属性访问:

BeanWrapper 允许以统一的方式访问 JavaBean 对象的属性,包括简单属性、复杂类型属性、集合和数组等。它支持通过属性路径(property path)来访问嵌套对象的属性,例如 person.address.streetName。

2.类型转换:

BeanWrapper 内置了对常见类型的转换支持,可以自动处理不同数据类型的转换。

可以注册自定义的 PropertyEditor 或使用 ConversionService 来实现更复杂的类型转换逻辑。

3.属性编辑器:

可以为特定的数据类型注册 PropertyEditor,这允许在从字符串到对象或反之的转换过程中进行定制化处理。

4.错误处理:

当尝试设置非法值或访问不存在的属性时,BeanWrapper 可以捕获并报告这些错误。

访问简单属性

java 复制代码
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class BeanWrapperExample {
    public static void main(String[] args) {
        // 创建一个目标对象
        Person person = new Person();

        // 创建 BeanWrapper 实例
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);

        // 设置属性值
        beanWrapper.setPropertyValue("name", "John Doe");
        beanWrapper.setPropertyValue("age", 30);

        // 获取属性值
        String name = (String) beanWrapper.getPropertyValue("name");
        int age = (Integer) beanWrapper.getPropertyValue("age");

        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
    }
}

class Person {
    private String name;
    private int age;

    // 必须提供 getter 和 setter 方法
    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;
    }
}

访问嵌套属性

java 复制代码
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class NestedPropertyAccess {
    public static void main(String[] args) {
        Person person = new Person();
        Address address = new Address();
        person.setAddress(address);
        
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);
        
        // 设置嵌套属性
        beanWrapper.setPropertyValue("address.street", "123 Main St");
        beanWrapper.setPropertyValue("address.city", "Springfield");
        
        // 获取嵌套属性
        String street = (String) beanWrapper.getPropertyValue("address.street");
        String city = (String) beanWrapper.getPropertyValue("address.city");
        
        System.out.println("Street: " + street); // 输出: Street: 123 Main St
        System.out.println("City: " + city);     // 输出: City: Springfield
    }
}

class Person {
    private String name;
    private int age;
    private Address address;

    // Getters and Setters
    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; }
    public Address getAddress() { return address; }
    public void setAddress(Address address) { this.address = address; }
}

class Address {
    private String street;
    private String city;

    // Getters and Setters
    public String getStreet() { return street; }
    public void setStreet(String street) { this.street = street; }
    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }
}

自动类型转换

java 复制代码
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class TypeConversion {
    public static void main(String[] args) {
        Person person = new Person();
        
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);
        
        // 设置属性值,自动类型转换
        beanWrapper.setPropertyValue("age", "30"); // 字符串 "30" 转换为 int 30
        
        // 获取属性值
        int age = (Integer) beanWrapper.getPropertyValue("age");
        
        System.out.println("Age: " + age); // 输出: Age: 30
    }
}

class Person {
    private String name;
    private int age;

    // Getters and Setters
    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; }
}

注册自定义 PropertyEditor

java 复制代码
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyEditorSupport;

public class CustomPropertyEditor {
    public static void main(String[] args) {
        Person person = new Person();
        
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);
        
        // 注册自定义 PropertyEditor
        beanWrapper.registerCustomEditor(Date.class, new DateEditor());
        
        // 设置日期属性
        beanWrapper.setPropertyValue("birthdate", "2023-01-01");
        
        // 获取日期属性
        Date birthdate = (Date) beanWrapper.getPropertyValue("birthdate");
        
        System.out.println("Birthdate: " + birthdate); 
        // 输出: Birthdate: Sun Jan 01 00:00:00 CST 2023
    }
}

class Person {
    private String name;
    private int age;
    private Date birthdate;

    // Getters and Setters
    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; }
    public Date getBirthdate() { return birthdate; }
    public void setBirthdate(Date birthdate) { this.birthdate = birthdate; }
}

class DateEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        try {
            setValue(new SimpleDateFormat("yyyy-MM-dd").parse(text));
        } catch (ParseException e) {
            throw new IllegalArgumentException("Invalid date format");
        }
    }
}

处理属性设置错误

java 复制代码
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.PropertyAccessException;

public class ErrorHandling {
    public static void main(String[] args) {
        Person person = new Person();
        
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);
        
        try {
            // 尝试设置一个不存在的属性
            beanWrapper.setPropertyValue("invalidProperty", "value");
        } catch (PropertyAccessException e) {
            System.out.println("Error: " + e.getMessage());
// 输出: Error: Invalid property 'invalidProperty' of bean class [Person]: 
// Bean property 'invalidProperty' is not readable or has an invalid getter 
// method: Does the return type of the getter match the parameter type 
// of the setter?
        }
    }
}

class Person {
    private String name;
    private int age;

    // Getters and Setters
    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; }
}
相关推荐
勤奋的知更鸟20 分钟前
Java 编程之模板方法模式
java·开发语言·模板方法模式
M1A134 分钟前
TCP/IP协议精解:IP协议——互联网世界的邮政编码系统
后端·网络协议·tcp/ip
逸风尊者41 分钟前
开发易掌握的知识:GeoHash查找附近空闲车辆
java·后端
lwb_011844 分钟前
SpringCloud——Gateway新一代网关
spring·spring cloud·gateway
碎叶城李白1 小时前
若依学习笔记1-validated
java·笔记·学习·validated
都叫我大帅哥2 小时前
🌊 Redis Stream深度探险:从秒杀系统到面试通关
java·redis
都叫我大帅哥2 小时前
Redis持久化全解析:从健忘症患者到记忆大师的逆袭
java·redis
程序猿阿越2 小时前
Kafka源码(一)Controller选举与创建Topic
java·后端·源码
程序员爱钓鱼2 小时前
Go语言项目工程化 — 常见开发工具与 CI/CD 支持
开发语言·后端·golang·gin