java orika_常见Bean映射工具分析评测及Orika介绍

Bean映射工具选择

工作中,我们经常需要将对象转换成不同的形式以适应不同的api,或者在不同业务层中传输对象而不同分层的对象存在不同的格式,因此我们需要编写映射代码将对象中的属性值从一种类型转换成另一种类型。

进行这种转换除了手动编写大量的get/set代码,还可以使用一些方便的类库,常用的有apache的BeanUtils,spring的BeanUtils,cglib的BeanCopier。

BeanUtils

apache的BeanUtils和spring的BeanUtils中拷贝方法的原理都是先用jdk中 java.beans.Introspector类的getBeanInfo()方法获取对象的属性信息及属性get/set方法,接着使用反射(Method的invoke(Object obj, Object... args))方法进行赋值。apache支持名称相同但类型不同的属性的转换,spring支持忽略某些属性不进行映射,他们都设置了缓存保存已解析过的BeanInfo信息。

BeanCopier

cglib的BeanCopier采用了不同的方法:它不是利用反射对属性进行赋值,而是直接使用ASM的MethodVisitor直接编写各属性的get/set方法(具体过程可见BeanCopier类的generateClass(ClassVisitor v)方法)生成class文件,然后进行执行。由于是直接生成字节码执行,所以BeanCopier的性能较采用反射的BeanUtils有较大提高,这一点可在后面的测试中看出。

Dozer

使用以上类库虽然可以不用手动编写get/set方法,但是他们都不能对不同名称的对象属性进行映射。在定制化的属性映射方面做得比较好的有Dozer,Dozer支持简单属性映射、复杂类型映射、双向映射、隐式映射以及递归映射。可使用xml或者注解进行映射的配置,支持自动类型转换,使用方便。但Dozer底层是使用reflect包下Field类的set(Object obj, Object value)方法进行属性赋值,执行速度上不是那么理想。

Orika

那么有没有特性丰富,速度又快的Bean映射工具呢,这就是下面要介绍的Orika,Orika是近期在github活跃的项目,底层采用了javassist类库生成Bean映射的字节码,之后直接加载执行生成的字节码文件,因此在速度上比使用反射进行赋值会快很多,下面详细介绍Orika的使用方法。

Orika使用

依赖

ma.glasnost.orika

orika-core

1.5.2

简单映射

构造一个MapperFactory

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

注册字段映射

mapperFactory.classMap(PersonSource.class, PersonDestination.class)

.field("firstName", "givenName")

.field("lastName", "sirName")

.byDefault()

.register();

进行映射

MapperFacade mapper = mapperFactory.getMapperFacade();

PersonSource source = new PersonSource();

// set some field values

...

// map the fields of 'source' onto a new instance of PersonDest

PersonDest destination = mapper.map(source, PersonDest.class);

在第二步进行的字段映射是双向的,我们可以从目标类型映射回源类型,byDefault()方法用于注册名称相同的属性(如果所有属性名称都相同则可以省略第2步),如果不希望某个字段参与映射,可以使用exclude方法

复杂映射

数组和List的映射

如果在目标类和目的类中分别有下面的属性

class BasicPerson {

private List nameParts;

// getters/setters omitted

}

class BasicPersonDto {

private String firstName;

private String lastName;

// getters/setters omitted

}

可以使用下面的方式进行映射:

mapperFactory.classMap(BasicPerson.class, BasicPersonDto.class)

.field("nameParts[0]", "firstName")

.field("nameParts[1]", "lastName")

.register();

类类型的映射

class Name {

private String first;

private String last;

private String fullName;

// getters/setters

}

class BasicPerson {

private Name name;

// getters/setters omitted

}

class BasicPersonDto {

private String firstName;

// getters/setters omitted

}

使用:

mapperFactory.classMap(BasicPerson.class, BasicPersonDto.class)

.field("name.first", "firstName")

.register();

自定义转换器

orika同样支持自定义转换器,将指定类型或指定名称的属性做映射时添加自定义操作,例如,将String类型的或某个属性映射后加一个前缀,或者将Integer类型映射后加1等:

public class MyConverter extends CustomConverter {

public MyDate convert(Date source, Type extends MyDate> destinationType) {

// return a new instance of destinationType with all properties filled

//example:source + 1;

}

}

Date为源类型中要做转换的属性数据类型,例如String、Integer等,MyDate为目标类型中要做转换的属性数据类型。

如果需要定义全局范围的转换:

ConverterFactory converterFactory = mapperFactory.getConverterFactory();

converterFactory.registerConverter(new MyConverter());

如果仅需要某几个属性使用转换器:

ConverterFactory converterFactory = mapperFactory.getConverterFactory();

converterFactory.registerConverter("myConverterIdValue", new MyConverter());

mapperFactory.classMap( Source.class, Destination.class )

.fieldMap("sourceField1", "sourceField2").converter("myConverterIdValue").add()

...

.register();

其他说明

Orika支持递归映射,将映射嵌套类直到用“简单”类型完成映射。它还包含故障保险,以正确处理正在尝试映射的对象中的递归引用。

在于spring集成时,可以将MapperFactory设置为单例

各映射工具的性能测试

构造一个包含普通类型及类类型的Bean对象,使用jmh微基准框架进行测试。由于jvm会对热点代码进行优化:方法反射调用次数超过阈值时会生成一个专用的MethodAccessor实现类,生成其中的invoke()方法的字节码进行执行。

故测试时每种方法先预热执行15次,而后再执行100次获取每次执行的平均时间:

Benchmark Mode Samples Score Score error Units

o.s.MyBenchmark.apache avgt 100 25.246 0.535 us/op

o.s.MyBenchmark.beanCopier avgt 100 0.004 0.000 us/op

o.s.MyBenchmark.byHand avgt 100 0.004 0.000 us/op

o.s.MyBenchmark.dozer avgt 100 5.855 0.260 us/op

o.s.MyBenchmark.orika avgt 100 0.353 0.017 us/op

o.s.MyBenchmark.spring avgt 100 0.627 0.020 us/op

统计报告中Units单位为微秒/次,由Score项可以看出,基于ASM的cglib BeanCopier拷贝速度基本和手写get/set方法的速度无异,其次的就是基于javassist的Orika了,Orika的速度是spring BeanUtils的两倍,Dozer的20倍,Apache BeanUtils的120倍。

综上,当属性名和属性类型完全相同时使用BeanCopier是最好的选择,当存在属性名称不同或者属性名称相同但属性类型不同的情况时,使用Orika是一种不错的选择。如果你对Orika感到不放心,实际应用前可以写个测试类查看它的转换结果是否符合预期。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/411020.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转载】别了,摩托罗拉(十六):平台之乱

除了愚蠢的价格战,占摩托罗拉总收入70%的手机业务在詹德手上能跌到今天不到10%的全球市场份额,重要的原因还有三个.一个是缺乏技术规划能力,导致手机操作系统平台战略混乱不堪,另一个是错失3G,还有一个原因则是在中国这个世界上最大的手机市场完败于诺基亚.  “手机的功能和易…

JavaScript 字符串转数字

parseFloat("22.34.5"); //returns 22.34 Math.floor(),不四舍五入 ,向下取整Math.floor(2.98)2 转载于:https://www.cnblogs.com/sea-stream/p/11100348.html

如何在Java中使用表达式_如何在java中计算表达式?

我在快速谷歌后发现了这段代码:import java.util.Stack;/*** Class to evaluate infix and postfix expressions.** author Paul E. Davis (feedbackwillcode4beer.com)*/public class InfixPostfixEvaluator {/*** Operators in reverse order of precedence.*/pri…

win7 'IIS APPPOOL\Classic .NET AppPool' 登录失败

进入iis管理器 本地应用程序池 选中classic. net appPool 选择右侧的 高级设置 进程模型 标识 将内置账户改为LOCAL SYSTEM 转载于:https://www.cnblogs.com/3rocks/archive/2010/06/02/1750091.html

MariaDB数据库5-password、galera

转载于:https://www.cnblogs.com/WIU1905/p/11100917.html

java 类型转换 安全_JAVA 类型转换指令

类型转换指令可以将两种不同的数值类型进行相互转换,这些转换操作一般用于实现用户代码中的显式类型转换操作,或者用来处理本节开篇所提到的字节码指令集中数据类型相关指令无法与数据类型一一对应的问题。Java虚拟机直接支持(即转换时无需显式的转换指令…

创建使用 Active Directory 模式隔离用户的新 FTP 站点

“使用 Active Directory 隔离用户”模式根据相应的 Active Directory 容器验证用户凭据,而不是搜索整个 Active Directory,因为这样做需要大量的处理时间。 备 注 此模式需要在 Windows Server 2003 家族的操作系统上运行 Active Directory 服务器。也…

小米推送之服务端简单开发

1.获取SDK,并写入常量表 2.引入MiPush_SDK_Sever.jar文件和json-simple-1.1.1.jar 3.开发服务端代码(这里是用别名进行推送) /*小米推送*//** * 指定alias推送(单个或多个) * * param messagePayload 消息 * param title 消息标题 *…

java源码导入eclipse_spring framework源码下载并导入eclipse

一. 准备工作1.下载安装sts(springsource推荐使用), 毕竟人家的框架用他自家的ide是最好的,当然sts也是基本eclipse的, 下载地址: http://www.springsource.org/downloads/sts-ggts2.下载安装gradle, spring 源码构建加入了gradle支持. gradle下载: http://www.gradle.org/down…

BI Publisher开发基本流程

1 配置文件位置 OracleBI/xmlp/XMLP/Admin/Configuration 2 登录到BI Publisher Enterprise (以下简称BIP) http://hostname:9704/xmlpserver/ 3 配置数据源 BIP支持四种类型的数据源连接 a) JDBC b) JNDI c) OLAP (多维服务器,如Essbase Hyperion&#…

用户账号系统(python)

user_list[]#所有学生账号储存在该列表中 for i in range(1,201):temp{name:stustr(i),password:ppsucstr(i),email:stustr(i)gd.com}user_list.append(temp) #通过for循环创建200个现有学生账号 print("欢迎使用公大教务系统!"…

查询优化(1)

--最近在看Inside Microsoft SQL Server 2005:Query Tuning and Optimization一书。其中有一段内容感觉归纳得不错,纠正了我以前的一些错误概念。 对查询我们可以从以下几个方面来考虑进行优化。 重写查询语句 除了尽量避免太复杂的谓词判断,我们还需要尽…

java二分法查找法算法_算法二:二分法查找(java语言)

说明:二分法查找* 解析:* 一维数组,二分法查找:假如有一组数为1,2,3,4,5,6,7,8,9,10要查给定的值7.* 可设三个变量low,mid,high分别指向数据的前,中间和后,mid(lowhigh)/2.* 注意&am…

四十大经(八正道)

中部117、四十大经 我听到这样: 有一次,世尊住在舍卫城祇树给孤独园。 在那里,世尊召唤比丘们:“比丘们!” “尊师!”那些比丘回答世尊。 世尊这么说: “我将教导你们圣正定的助伴、资粮&…

[原创]在windows下搭建基于apache的SVN环境

[原创]在windows下搭建基于apache的SVN环境 1 软件下载: 在http://httpd.apache.org/download.cgi,下载: apache_2.2.14-win32-x86-openssl-0.9.8k.msi 在 http://subversion.tigris.org/,下载: Setup-Subversion-1.6.…