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; }
}
相关推荐
方圆想当图灵3 分钟前
缓存之美:万文详解 Caffeine 实现原理(下)
java·redis·缓存
栗豆包18 分钟前
w175基于springboot的图书管理系统的设计与实现
java·spring boot·后端·spring·tomcat
等一场春雨1 小时前
Java设计模式 十四 行为型模式 (Behavioral Patterns)
java·开发语言·设计模式
萧若岚1 小时前
Elixir语言的Web开发
开发语言·后端·golang
Channing Lewis1 小时前
flask实现重启后需要重新输入用户名而避免浏览器使用之前已经记录的用户名
后端·python·flask
Channing Lewis1 小时前
如何在 Flask 中实现用户认证?
后端·python·flask
酱学编程2 小时前
java中的单元测试的使用以及原理
java·单元测试·log4j
我的运维人生2 小时前
Java并发编程深度解析:从理论到实践
java·开发语言·python·运维开发·技术共享
一只爱吃“兔子”的“胡萝卜”2 小时前
2.Spring-AOP
java·后端·spring
HappyAcmen2 小时前
Java中List集合的面试试题及答案解析
java·面试·list