`
一江春水邀明月
  • 浏览: 79033 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java Bean 拷贝工具Orika 介绍

 
阅读更多

首发http://wangbt5191-hotmail-com.iteye.com/blog/1632444, 转载请给出原始链接。

最近笔者在项目调优过程中发现公司的老产品在使用Dozer 做Bean Copy 性能非常慢,发现在这个领域业界还是有很多新秀的。 Orika 应该就算一个比较好的吧。

Orika 的官方主页请戳这里 。 Orika  在自己的官方站点上声称自己是simpler, better and faster Java bean mapping framework

 

性能数据:

废话不多说, 先来上性能数据:

dozerCost_ = 1260ms  page number = 1  size = 50
 orikaCost_ = 72ms  page number = 2  size = 50
 dozerCost_ = 53ms  page number = 3  size = 50
 orikaCost_ = 3ms  page number = 4  size = 50
 dozerCost_ = 35ms  page number = 5  size = 50
...
orikaCost_ = 11ms  page number = 994  size = 50
 dozerCost_ = 32ms  page number = 995  size = 50
 orikaCost_ = 2ms  page number = 996  size = 50
 dozerCost_ = 26ms  page number = 997  size = 50
 orikaCost_ = 2ms  page number = 998  size = 50
 dozerCost_ = 36ms  page number = 999  size = 50
 orikaCost_ = 16ms  page number = 1000  size = 50
total orika cost = 2250ms
total dozer cost = 16776ms
 

优势:

1. 性能

    大概是Dozer的8-10 倍, 这个上面的已经做了描述

2. 内存消耗

   大概是Dozer内存消耗的一半多点。 为什么做到这点的还没想清楚, 估计是因为运行期不需要维护复杂的Mapping 关系。 不需要大量的Mapping 关系查找以及需要的对这些查找优化所消耗的空间。

3.  简单

  Orika的代码短小精悍, 而且可读性非常强, Dozer如果要加减一个功能, 不才完全没有信心, Orika 我还是可以偶尔在Orika里面打几个酱油的。

 

工作原理:

1. 快在哪里

Orika 的工作原理是在预先生成运行期需要运行的目标代码类, 这个类的最终实现类里面就两个方法  mapAtoB 和mapBtoA. 这里我取一个代码片段分析下,

 

package ma.glasnost.orika.generated;
public class OrikaAbstractVOAbstractBOMapper9079818 extends ma.glasnost.orika.impl.GeneratedMapperBase {
	public void mapAtoB(java.lang.Object a, java.lang.Object b, ma.glasnost.orika.MappingContext mappingContext) {
		super.mapAtoB(a,b, mappingContext);
		com.best.oasis.genidc.biz.common.model.AbstractBO source =
				 (com.best.oasis.genidc.biz.common.model.AbstractBO) a;
		com.best.oasis.genidc.common.vo.AbstractVO destination =
				 (com.best.oasis.genidc.common.vo.AbstractVO) b;
		if(((java.lang.Long)source.getCreatorId()) != null){
			destination.setCreatorId(((java.lang.Long)source.getCreatorId()));
		}
		if(((java.lang.Long)source.getCreatorId()) != null){
			if(((java.lang.Long)source.getCreatorId()) != null){
				destination.setCreatorName((java.lang.String) mapperFacade.convert(((java.lang.Long)source.getCreatorId()), usedTypes[2], usedTypes[3], "genidcUserNameConverter"));
			}
		}
		if(((java.lang.Long)source.getUpdatorId()) != null){
			destination.setUpdatorId(((java.lang.Long)source.getUpdatorId()));
		}
		if(((java.lang.Long)source.getUpdatorId()) != null){
			if(((java.lang.Long)source.getUpdatorId()) != null){
				destination.setUpdatorName((java.lang.String) mapperFacade.convert(((java.lang.Long)source.getUpdatorId()), usedTypes[2], usedTypes[3], "genidcUserNameConverter"));
			}
		}
		if(((com.best.oasis.genidc.biz.system.model.SysCodeInfo)source.getStatus()) != null){
			if(((java.lang.String)((com.best.oasis.genidc.biz.system.model.SysCodeInfo)source.getStatus()).getCnCodeName()) != null){
				destination.setStatusName(((java.lang.String)((com.best.oasis.genidc.biz.system.model.SysCodeInfo)source.getStatus()).getCnCodeName()));
			}
		}
		if(((com.best.oasis.genidc.biz.system.model.SysCodeInfo)source.getStatus()) != null){
			if(((java.lang.Long)((com.best.oasis.genidc.biz.system.model.SysCodeInfo)source.getStatus()).getId()) != null){
				destination.setStatusId(((java.lang.Long)((com.best.oasis.genidc.biz.system.model.SysCodeInfo)source.getStatus()).getId()));
			}
		}
		if(((com.best.oasis.genidc.biz.system.model.SysCodeInfo)source.getStatus()) != null){
			if(((java.lang.String)((com.best.oasis.genidc.biz.system.model.SysCodeInfo)source.getStatus()).getCode()) != null){
				destination.setStatusCode(((java.lang.String)((com.best.oasis.genidc.biz.system.model.SysCodeInfo)source.getStatus()).getCode()));
			}
		}
		if(customMapper != null) {
			 customMapper.mapAtoB(source, destination, mappingContext);
		}
	}

	public void mapBtoA(java.lang.Object a, java.lang.Object b, ma.glasnost.orika.MappingContext mappingContext) {
		.....
	}
 

 

从生成的目标代码来说, 这两个方法的目的就是调父类方法去拷贝父类的映射关系的字段然后拷贝当前类的映射关系的字段。  这个目标生成类已经是和手动写的映射代码一样的了。

这段代码是配置以下配置生成的

 

<mapping>
	<class-a map-null="false">com.best.oasis.genidc.biz.common.model.AbstractBO
	</class-a>
	<class-b>com.best.oasis.genidc.common.vo.AbstractVO</class-b>
	<fields>
		<field><a>status.id</a><b>statusId</b></field>
		<field type="one-way"><a>status.cnCodeName</a><b>statusName</b></field>
		<field type="one-way"><a>status.code</a><b>statusCode</b></field>
		<field type="one-way" custom-converter="genidcUserNameConverter"><a>creatorId</a><b>creatorName</b></field>
		<field type="one-way" custom-converter="genidcUserNameConverter"><a>updatorId</a><b>updatorName</b></field>
		<field><a>creatorId</a><b>creatorId</b></field>
		<field><a>updatorId</a><b>updatorId</b></field>
	</fields>
</mapping>

 Orika 的设计思路就是预先通过javaassist 把Java Bean 之间的映射关系一次性生成目标拷贝方法代码。 这样就可以避免在Bean 映射环节一次次的读取映射规则。 这就是Orika 性能提升的原因。

。 理论上以生成的目标Java 代码来运行映射是拷贝模式所能取到性能最大值的方法。 当然, 如果你说跳出Java, 那要另当别论。

 

2. 目标代码如何生成

感兴趣的同学我们继续留在这节里面看一下Orika怎么做到生成目标代码的:

 

 

 
Orika 以MapperFactory 来管理Bean-Bean 之间的映射空间和生成客户端使用Map 映射的门脸对象, 在使用之前, Orika 会调用同步的build方法来进行对所有注册的Bean 映射关系进行运行期类生成的工作。

在最终build 方法里面, 生成GeneratedSourceCode mapperCode 实例, 在截图中我们可以看到它维护了一个StringBuilder类型的变量, 这个变量的值就是我们需要生成的最终目标类的源代码。 然后mapperCode会负责调用getInstance 方法来使用StringBuilder中的文本内容编译目标类, 然后获取实例。

有追问精神的同学会问具体如何通过规则得到StringBuilder 里面的文本内容, 就是在上面截图里面的addMapMethod 方法的两次调用做的, 分别生成mapAtoB 和生成mapBtoA 方法, 由于Orika 的良好封装, 这个代码也是非常易懂易读的, 有兴趣的童鞋可以自行去阅读。 我这里只给插几个路标给大家指个大方向。

3. 接下来我们看看映射的时候如何使用目标代码的

从上图的Debug的Trace我们可以看到在映射的时候是会最终调用目标方法的mapAtoB 方法(或者mapBtoA), 通过上面生成的mapAtoB的代码阅读我们可以看到它会调用父类方法的 super.mapAtoB(a,b, mappingContext); 就是截图这里的, 我们可以看到它其实就是做了对要映射bean 的父类映射的关系的属性拷贝。

 

 

  • 大小: 142.8 KB
  • 大小: 349.5 KB
  • 大小: 249.6 KB
分享到:
评论
2 楼 一江春水邀明月 2013-11-05  
有使用,比较稳定。 但是需要注意的是Orika实例不能做lazy load, 比较安全的做法是在App 启动的时候加载完系统中所有该映射的class 生成映射目标类。 如果是lazy 加载, 在多线程同时去生成目标映射类的时候, 会有一些问题。
1 楼 千钧一发 2013-11-01  
请教下,Orika有在生产环境实践过吗?
稳定吗?

相关推荐

    orika Java实例Demo

    Orika是一个高性能、易用的Java Bean到Bean映射库,它简化了对象之间的数据转换过程。在这个实例Demo中,我们将深入理解Orika的工作原理,以及如何在Java项目中有效地使用它进行对象拷贝。 ### 1. Orika简介 Orika...

    orika,更简单、更好和更快的java bean映射框架.zip

    奥里卡(Orika)是一个Java Bean映射框架,它为开发者提供了在Java对象之间进行自动数据转换的简便方法。这个框架的主要目标是简化对象之间的属性映射过程,减轻开发人员手动编写转换代码的负担。Orika 1.5.4是其一...

    orika:更简单,更好,更快的Java bean映射框架

    Orika是Java Bean映射框架,它(除其他功能外)将数据从一个对象递归复制到另一个对象。 在开发多层应用程序时,它可能非常有用。为什么? 难以处理手动编码和基于反射的映射器? Orika可用于简化一个对象层与另一...

    orika-core-1.5.4-API文档-中文版.zip

    标签:glasnost、orika、core、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...

    orika-eclipse-tools-1.1.8.zip

    Orika是一个高性能、易用的Java Bean到Java Bean映射框架,它简化了对象之间的数据转换过程。 【描述】"hadoop-maven-plugin.zip" 描述的是Apache Hadoop Maven插件的一个版本,这个插件是专门为Apache Hadoop项目...

    orika-core-1.5.4-API文档-中英对照版.zip

    标签:glasnost、orika、core、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,...

    JavaBean映射框架Orika.zip

    Orika 是一个 Java Bean 映射框架。示例代码:mapperFactory.classMap(BasicPerson.class, BasicPersonDto.class)  .mapNulls(true).mapNullsInReverse(true)  .field("field1", "fieldOne")  .mapNulls(false)...

    Oracle Java JDK 17

    Oracle Java Development Kit (JDK) 17 是Java编程语言的核心工具集,它包含了开发者编译、调试和运行Java应用程序所需的所有组件。JDK 17是Java的一个长期支持(LTS)版本,这意味着它将获得更长时间的技术支持,...

    orika-sample:使用“ ma.glasnost.orika”的样本

    "orika-sample:使用“ma.glasnost.orika”的样本"是一个关于Java对象映射库Orika的实践项目。Orika是一个高性能、易用的对象映射框架,它简化...无论是对于简化代码还是提高开发效率,Orika都是Java开发者的强大工具。

    orika:从 code.google.comporika 自动导出

    Orika 是一个 Java Bean 映射框架,它递归地将数据(以及其他功能)从一个对象复制到另一个对象。 它在开发多层应用程序时非常有用。 为什么? 正在努力使用手工编码和基于反射的映射器? Orika 可用于简化一个...

    orika-spring-boot-starter:适用于Orika的Spring Boot Starter

    Java 8、9、10、11 Spring Boot 2.1.3 奥里卡1.5.4 用法 添加依赖 “ orika-spring-boot-starter”在Maven中央存储库中发布。 如果使用的是Maven,请添加以下依赖项。 &lt; groupId&gt;...

    大学生毕设+基于SpringBoot和Layui、Mybatis带GUI界面+仿BOSS直聘招聘网站系统(前后端源码+数据库)

    招聘网站,仿boss直聘的网站,可以在线修改简历,...|orika|1.5.4|更快的bean复制工具| |lombok|1.18.8|简化对象封装工具| |hutool|4.5.0|更适合国人的java工具集| |swagger-bootstrap|1.9.3|基于swagger,更便于国人使

    Orika-core使用总结整理.html

    Orika-core使用总结整理

    Orika-core使用总结整理.md

    Orika-core使用总结整理

    CopyObjectUtils.java

    Orika工具类包含常用转化

    orika-core-1.5.4.jar中文-英文对照文档.zip

    中文-英文对照文档,中英对照文档,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【***.jar中文文档.zip】,再解压其中的 【***-...

    spring-oxm-1.5.4.jar

    spring-oxm-1.5.4.jar

    find-restaurants-api

    寻找餐厅API ...要求: ...实体转换:Orika 附加的东西: Lombok编写更少的代码 要查看Swagger 2用户界面,请执行以下操作: 测试集成测试使用Docker-client和Flyway使用JUnit ClassRule填充数据库

Global site tag (gtag.js) - Google Analytics