BeanWrapper提供了设置和获取属性值(单个的或者是批量的),获取属性描述信息、查询只读或者可写属性等功能。不仅如此,BeanWrapper还支持嵌套属性,你可以不受嵌套深度限制对子属性的值进行设置。所以,BeanWrapper无需任何辅助代码就可以支持标准JavaBean的PropertyChangeListeners和VetoableChangeListeners。除此之外,BeanWrapper还提供了设置索引属性的支持。通常情况下,我们不在应用程序中直接使用BeanWrapper而是使用DataBinder 和BeanFactory。
BeanWrapper这个名字本身就暗示了它的功能:封装了一个bean的行为,诸如设置和获取属性值等。
设置和获取属性值以及嵌套属性
设置和获取属性可以通过使用重载的setPropertyValue(s)和getPropertyValue(s)方法来完成。在Spring自带的JavaDoc中对它们有详细的描述。值得一提的是,在这其中存在一些针对对象属性的潜在约定规则。下面是一些例子:
表 5.1. 属性示例
表达式说明
name 指向属性name,与getName() 或 isName() 和 setName()相对应。
account.name 指向属性account的嵌套属性name,与之对应的是getAccount().setName()和getAccount().getName()
account[2] 指向索引属性account的第三个元素,索引属性可能是一个数组(array),列表(list)或其它天然有序的容器。
account[COMPANYNAME] 指向一个Map实体account中以COMPANYNAME作为键值(key)所对应的值
例子1:
public interface Action { public String execute(); } public class UpperAction implements Action { private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String execute() { return (msg.toUpperCase()); } }
设置值方法1 (JAVA反射):
我们知道,如果动态设置一个对象属性,可以借助Java的Reflection机制完成:
try { Class cls = Class.forName("net.sg.spring.service.UpperAction"); Object obj = cls.newInstance(); Method method = cls.getMethod("setMsg", new Class[]{String.class}); method.invoke(obj, new Object[]{"hello"}); System.out.println(((UpperAction) obj).execute()); } catch (Exception e) {}
设置值方法2( BeanWrapper方式):
try { Class cls = Class.forName("net.sg.spring.service.UpperAction"); Object obj = cls.newInstance(); BeanWrapper beanWrapper = new BeanWrapperImpl(obj); beanWrapper.setPropertyValue("msg","hello"); System.out.println(beanWrapper.getPropertyValue("msg")); System.out.println(((UpperAction)obj).getMsg()); } catch (Exception e) {}
例子2:
public class Employee { private float salary; public float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } }
public class Company { private String name; private Employee managingDirector; public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Employee getManagingDirector() { return this.managingDirector; } public void setManagingDirector(Employee managingDirector) { this.managingDirector = managingDirector; } }
BeanWrapper company = BeanWrapperImpl(new Company()); // setting the company name.. company.setPropertyValue("name", "Some Company Inc."); // ... can also be done like this: PropertyValue value = new PropertyValue("name", "Some Company Inc."); company.setPropertyValue(value); // ok, let's create the director and tie it to the company: BeanWrapper jim = BeanWrapperImpl(new Employee()); jim.setPropertyValue("name", "Jim Stravinsky"); company.setPropertyValue("managingDirector", jim.getWrappedInstance()); // retrieving the salary of the managingDirector through the company Float salary = (Float) company.getPropertyValue("managingDirector.salary");