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; }
}
相关推荐
g***969021 分钟前
【Spring Boot 实现 PDF 导出】
spring boot·后端·pdf
u***420722 分钟前
Ubuntu介绍、与centos的区别、基于VMware安装Ubuntu Server 22.04、配置远程连接、安装jdk+Tomcat
java·ubuntu·centos
charlie1145141911 小时前
从 0 开始:在 WSL + VSCode 上利用 Maven 构建 Java Spring Boot 工程
java·笔记·vscode·后端·学习·maven·springboot
tuokuac1 小时前
Maven中的属性占位符的用法
java·maven
芒克芒克1 小时前
Maven 项目管理从入门到进阶:基础与高级实战全解析
java·maven
k***3882 小时前
SpringBoot Test详解
spring boot·后端·log4j
z***89713 小时前
SpringBoot Maven 项目 pom 中的 plugin 插件用法整理
spring boot·后端·maven
憧憬blog4 小时前
【Kiro开发集训营】拒绝“屎山”堆积:在 Kiro 中重构“需求-代码”的血缘关系
java·开发语言·kiro
e***74954 小时前
Spring Security 官网文档学习
java·学习·spring
n***i955 小时前
Java NIO文件操作
java·开发语言·nio