Sunday, December 9, 2012

apache commons --- BeanUtils

什么是 beans,一般是指有 default constructor,且有 getter/setter 的类,通常的 getter/setter 有三种:
  • 简单的就是 get 不带参数,set 传递一个,表示设置一个简单的属性
  • indexed 相当于这个属性是个 List 之类的东西,因此 get 传递 int,set 传递 int 和值
  • mapped 相当于这个属性是个 String 到某个类型的 Map,因此和 indexed 类似,但是多传递的是个 String
这个包提供了对这三类方法的封装,都使用 PropertyUtils 里面的一些静态方法,通过传递字符串来表示对应的 property,如
  • get/setSimpleProperty 需要传递对象和属性名以及值(对 setter)
  • get/setIndexedProperty 的属性名就变成一个名字后面加上类似“[1]” 表示位置的信息,当然也可以按照 Simple 的形式,里面加上 int 参数作为位置
  • get/setMappedProperty 类似加上的后缀形式是“(key)”,当然也可以多传递一个 String 表示 key
当然 PropertyUtils 还支持嵌套,即如果某个属性仍然是一个 bean,我们可以使用 getNestedProperty 来处理,这时的 property 之间用点连接。为了简化使用,PropertyUtils 提供了 get/setProperty 方法,可以自动的判断使用上面哪种方法访问到对应的 property。

由于 bean 对应的对象的属性本质上是静态(即在 load 时确定后无法进行修改,相关讨论见上篇 blog),这个 package 还提供了模拟出来的动态的 bean,实现为 DynaBean,这种对象可以用 PropertyUtils 一样的处理,这样就形成了一种形式上的抽象。DynaBean 如名所说 property 的个数是可以运行时决定的。通常我们需要使用 DynaProperty(使用一个 String 表示名字,Class 表示类型)来表述一个属性,然后使用一个 DynaProperty 数组表示一个 DynaClass 包含的所有属性,之后就能创建一个 BasicDynaClass 对象了,通过其 newInstance 方法就能创建我们的 DynaBean 对象,这些对象本身可以通过 get/set 设置前面定义的属性。

岔开说一句的是通过 ResultSetDynaClass(通过一个 ResultSet 创建的 DynaClass 对象)我们可以很容易将使用 JDBC 系列获得的行转换成为 DynaClass 的对象,其 iterator 方法返回的就是一个 DynaBean 的迭代器,供我们遍历数据使用。类似另一个类称为 RowSetDynaClass 是进行的 copy,区别在于前者由于没有 copy 需要保留这个 ResultSet 对象,后者创建后就不再与 ResultSet 有关系了。

既然 DynaBean 看起来比一般的 bean 要强大,那么自然我们也希望能将一般的 bean 转换成为 DynaBean,这可以使用 WrapDynaBean 来创建。另外,通过 LazyDynaBean 我们可以在需要的时候添加/删除属性(add/remove 方法),而不是像前面的 SimpleDynaBean 要求全部都在构造的时候说明。

使用这种 bean 策略的常见用途在于某些情况下我们拿到的数据是一个 map,我们希望将对应 key 的一些数据通过转换放置到某些 bean 里面供 Java 程序使用,这个常见的操作(populate)由 BeanUtils 提供,它依赖于一个叫 ConvertUtils 的类完成一些具体的转换(字符串到某些类的转换,通过 register 这些类对应的 Converter 即可)。

最后说一下 BeanUtils 还提供了一些类似 C++ STL 里面的一些对 collection of beans 的工具,可以简化很多 code,相关的类有,BeanValuePropertyChangeClosure、BeanValueProperty*Predicate、BeanValuePopertyTransformer。

参看这个 user guideapi doc

No comments:

Post a Comment