Java bean常见映射工具分析和比较
1. 概述
日常Java开发项目中,我们经常需要将对象转换成其他形式的对象,因此我们需要编写映射代码将对象中的属性值从一种类型转换成另一种类型。
进行这种转换除了手动编写大量的get/set
代码,还可以使用一些方便的类库:
apache的BeanUtils
spring的BeanUtils
cglib的BeanCopier
。
2.比较
2.1 BeanUtils
BeanUtils一套开发包,Apache公司提供 ,专门进行javabean操作,在web层各种框架中被使用,例如:struts 使用BeanUtils操作JavaBean 。
实例
1、下载BeanUtils的jar :commons-beanutils 、commons-logging,需要同时下载两个jar包。(BeanUtils依赖Logging的jar包 )
2、将beanutils和logging的 jar包复制 工程/WebContent/WEB-INF/lib
apache的BeanUtils
和spring的BeanUtils
中拷贝方法的原理都是先用jdk中 java.beans.Introspector
类的getBeanInfo()
方法获取对象的属性信息及属性get/set方法,接着使用反射(Method
的invoke(Object obj, Object... args)
)方法进行赋值。apache支持名称相同但类型不同的属性的转换,spring支持忽略某些属性不进行映射,他们都设置了缓存保存已解析过的BeanInfo
信息。
commons.beanutils-1.8.3.jar
spring.beans-4.2.3.RELEASE.jar
<dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency>
import org.apache.commons.beanutils.BeanUtils;
public class TestBeanUtils extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.设置编码
req.setCharacterEncoding(“utf-8”);
//2.获取数据
Map<String, String[]> params = req.getParameterMap();
//System.out.println(params);
//3.使用BeanUtils工具类封装User对象
Users user = new Users();
try {
BeanUtils.populate(user, params);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(user);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
2.2 BeanCopier
cglib的BeanCopier
采用了不同的方法:它不是利用反射对属性进行赋值,而是直接使用ASM的MethodVisitor
直接编写各属性的get/set
方法(具体过程可见BeanCopier
类的generateClass(ClassVisitor v)
方法)生成class文件,然后进行执行。由于是直接生成字节码执行,所以BeanCopier
的性能较采用反射的BeanUtils
有较大提高,这一点可在后面的测试中看出。
2.3 Dozer
使用以上类库虽然可以不用手动编写get/set
方法,但是他们都不能对不同名称的对象属性进行映射。在定制化的属性映射方面做得比较好的有Dozer,Dozer支持简单属性映射、复杂类型映射、双向映射、隐式映射以及递归映射。可使用xml或者注解进行映射的配置,支持自动类型转换,使用方便。但Dozer底层是使用reflect包下Field
类的set(Object obj, Object value)
方法进行属性赋值,执行速度上不是那么理想。
2.4 Orika
那么有没有特性丰富,速度又快的Bean映射工具呢,这就是下面要介绍的Orika,Orika是近期在github活跃的项目,底层采用了javassist类库生成Bean映射的字节码,之后直接加载执行生成的字节码文件,因此在速度上比使用反射进行赋值会快很多,下面详细介绍Orika的使用方法。
3. Orika使用
依赖
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.5.2</version><!-- or latest version -->
</dependency>