Dynamic Bean

突然对一些基础类库的代码感了兴趣,于是最先看起了Apache的commons-beanutils这个包,然后顺藤摸瓜式的了解JavaBeans和Dynamic Bean相关的知识。

common-beanutils-1.9.2

此包主要功能如下:

创建动态的JavaBean及相关的util类型代码。

主要类的关系图如下:

主要类图

  • DynaClass, DynaProperty, DynaBean用来动态生成JavaBean, 主要使用了Java的原生包:java.lang.reflect & java.beans

  • BeanUtilsBean是单例, 包含拷贝属性,克隆bean等util方法。

举个栗子

import org.apache.commons.beanutils.BasicDynaClass;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaClass;
import org.apache.commons.beanutils.DynaProperty;

/**
 *
  * @author www.javadb.com
  */
public class DynaBeanExample {

    private final String NR_OF_WHEELS = "numberOfWheels";

    private void runExample() {

        DynaClass dynaClass = new BasicDynaClass("Car", null,
            new DynaProperty[]{
                new DynaProperty(NR_OF_WHEELS, Integer.TYPE)});

        try {
            DynaBean car = dynaClass.newInstance();
            car.set(NR_OF_WHEELS, 4);

               System.out.println("Number of wheels: " + car.get(NR_OF_WHEELS));

            System.out.println("DynaBean is instance of DynaClass: " + car.getDynaClass().getName());

        } catch (IllegalAccessException | InstantiationException ex) {
            System.err.println(ex.getMessage());
        }
    }

   /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        DynaBeanExample ac = new DynaBeanExample();
        ac.runExample();
    }
}

所以看着这个使用的方式感觉还是蛮有意思的,可以动态的生成自己想要的“Java Bean”

这个时候就开始好奇这个包会有什么问题呢?比如性能上面?然后就搜到了这个Drools很早就开始反对使用这种方式来构建Java Bean,理由很简单,系统兼容性不好,说这个包虽然实现的Dynamic Bean的功能,但是生成的DynaBean是不符合JavaBeans的规范的,将会引发一系列的代码兼容性的问题,所以不建议商业系统环境使用这个包—例如主流的ORM框架都只支持规范的JavaBeans。我们看代码可以发现DynaBean使用的是一个Map<String, DynaProperty>来存储属性的。

那么现在问题来了,什么是JavaBeans ?

JavaBean

参阅JavaBeans(TM) Specification官方的文档,移步解读大纲。所以这个包是通过使用Introspection相关的类来实现Dynamic Bean,而不是构造符合JavaBeans规范的类.所以Drools就推荐使用了cglib来实现Dynamic Bean, 移步此参考