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());
}
}


[b] 设置值方法1 (JAVA反射):[/b]


我们知道,如果动态设置一个对象属性,可以借助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) {}



[b] 设置值方法2( BeanWrapper方式): [/b]


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) {}



[b] 例子2: [/b]


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");