一、简介:


BeanUtils提供对 Java反射和自省API的包装。其主要目的是利用反射机制对JavaBean的属性进行处理。我们知道,一个JavaBean通常包含了大量的属性,很多情况下,对JavaBean的处理导致大量get/set代码堆积,增加了代码长度和阅读代码的难度。


二、用法:


BeanUtils是这个包里比较常用的一个工具类,这里只介绍它的copyProperties()方法。该方法定义如下:


public static void copyProperties(java.lang.Object dest,java.lang.Object orig)
throws java.lang.IllegalAccessException,
java.lang.reflect.InvocationTargetException



如果你有两个具有很多相同属性的JavaBean,一个很常见的情况就是Struts里的PO对象(持久对象)和对应的ActionForm,例如 Teacher和TeacherForm。我们一般会在Action里从ActionForm构造一个PO对象,传统的方式是使用类似下面的语句对属性逐个赋值:

//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//构造Teacher对象
Teacher teacher=new Teacher();
//赋值
teacher.setName(teacherForm.getName());
teacher.setAge(teacherForm.getAge());
teacher.setGender(teacherForm.getGender());
teacher.setMajor(teacherForm.getMajor());
teacher.setDepartment(teacherForm.getDepartment());

//持久化Teacher对象到数据库
HibernateDAO=;
HibernateDAO.save(teacher);

而使用BeanUtils后,代码就大大改观了,如下所示:
//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//构造Teacher对象
Teacher teacher=new Teacher();
//赋值
BeanUtils.copyProperties(teacher,teacherForm);
//持久化Teacher对象到数据库
HibernateDAO=;
HibernateDAO.save(teacher);



如果Teacher和TeacherForm间存在名称不相同的属性,则BeanUtils不对这些属性进行处理,需要程序员手动处理。例如 Teacher包含modifyDate(该属性记录最后修改日期,不需要用户在界面中输入)属性而TeacherForm无此属性,那么在上面代码的 copyProperties()后还要加上一句:

teacher.setModifyDate(new Date());



怎么样,很方便吧!除BeanUtils外还有一个名为PropertyUtils的工具类,它也提供copyProperties()方法,作用与BeanUtils的同名方法十分相似,主要的区别在于后者提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而前者不支持这个功能,但是速度会更快一些。BeanUtils支持的转换类型如下:

* java.lang.BigDecimal
* java.lang.BigInteger
* boolean and java.lang.Boolean
* byte and java.lang.Byte
* char and java.lang.Character
* java.lang.Class
* double and java.lang.Double
* float and java.lang.Float
* int and java.lang.Integer
* long and java.lang.Long
* short and java.lang.Short
* java.lang.String
* java.sql.Date
* java.sql.Time
* java.sql.Timestamp



这里要注意一点,java.util.Date是不被支持的,而它的子类java.sql.Date是被支持的。因此如果对象包含时间类型的属性,且希望被转换的时候,一定要使用java.sql.Date类型。否则在转换时会提示argument mistype异常。


三、优缺点:


Apache Jakarta Commons项目非常有用。我曾在许多不同的项目上或直接或间接地使用各种流行的commons组件。其中的一个强大的组件就是BeanUtils。我将说明如何使用BeanUtils将local实体bean转换为对应的value 对象:


BeanUtils.copyProperties(aValue, aLocal)


上面的代码从aLocal对象复制属性到aValue对象。它相当简单!它不管local(或对应的value)对象有多少个属性,只管进行复制。我们假设local对象有100个属性。上面的代码使我们可以无需键入至少100行的冗长、容易出错和反复的get和set方法调用。这太棒了!太强大了!太有用了!

现在,还有一个坏消息:使用BeanUtils的成本惊人地昂贵!我做了一个简单的测试,BeanUtils所花费的时间要超过取数据、将其复制到对应的 value对象(通过手动调用get和set方法),以及通过串行化将其返回到远程的客户机的时间总和。所以要小心使用这种威力!Apache Common BeanUtil是一个常用的在对象之间复制数据的工具类,著名的web开发框架struts就是依赖于它进行ActionForm的创建。
BeanUtil最常用的类是org.apache.commons.beanutils.BeanUtils。BeanUtils最常用的方法为:copyProperties
(java.lang.Object dest, java.lang.Object orig)

把orig中的值copy到dest中.2. public java.util.Map describe(java.lang.Object bean)

把Bean的属性值放入到一个Map里面。3.
populate
(java.lang.Object bean, java.util.Map properties)

把properties里面的值放入bean中。4. public void setProperty(java.lang.Object bean, java.lang.String name, java.lang.Object value)

设置Bean对象的名称为name的property的值为value.5. public String getProperty(java.lang.Object bean, java.lang.String name)取得bean对象中名为name的属性的值。详细的使用方法可以参见官方网站:http://jakarta.apache.org/commons/beanutils/Apache Common BeanUtil的​​常见​​使用​​场景​​。
1.
同类之间不同对象要求进行数据复制。


User user1
=
…;
User user2
=
…;
BeanUtils. copyProperties(user2,user1);
2.
不同类不同对象之间的数据复制。

UserForm userForm =
…;
User user =
…;
BeanUtils. copyProperties(user, userForm);

相信经常使用struts的人,一定会很熟悉上面的代码。
这是一个典型把页面的value object数据复制到domain object的例子。<!--[if !supportLists]-->3. <!--[endif]-->对象数据和Map之间互相转化。

User user = …;
Map userMap = BeanUtils.describe(user);
Map userMap = …;
User user = …;
BeanUtils.populate(user,userMap);
Map可以看成一个动态数据容器,作为VO很适合在不同层之间传播数据,作为PO也可以动态存储字段信息,
合理运用可以减少程序很多修改和维护工作。所以让bean和map之间方便的进行数据填充,非常必要。