首发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
分享到:
相关推荐
Orika是一个高性能、易用的Java Bean到Bean映射库,它简化了对象之间的数据转换过程。在这个实例Demo中,我们将深入理解Orika的工作原理,以及如何在Java项目中有效地使用它进行对象拷贝。 ### 1. Orika简介 Orika...
奥里卡(Orika)是一个Java Bean映射框架,它为开发者提供了在Java对象之间进行自动数据转换的简便方法。这个框架的主要目标是简化对象之间的属性映射过程,减轻开发人员手动编写转换代码的负担。Orika 1.5.4是其一...
11KW OBC两电平pfc+cllc仿真源码实现:单相与三相兼容版双向控制研究,11KW OBC两电平pfc+cllc仿真源码实现:单相与三相兼容版,实现双向控制策略,11KW OBC两电平pfc+cllc仿真,源代码实现。 注意:已成单相,三相兼容版仿真文件。 双向控制。 ,核心关键词:11KW OBC两电平pfc; CLLC仿真; 源代码实现; 单相三相兼容; 双向控制。,11KW OBC单相与三相兼容版仿真:两电平PFC+CLLC双向控制源代码实现
3GPP R15 38.331 5G NR无线资源控制(RRC)协议规范解析
五运六气YUNQI_V471_SRC_D1023
19考试真题最近的t63.txt
基于MATLAB的牛拉法电力系统潮流计算程序,结合BPA方法,附参考文献,适合基础学习与拓展创新,基于MATLAB的牛拉法电力系统潮流计算程序:涵盖基础学习与拓展创新,附参考文献,牛拉法电力系统潮流计算 MATLAB编写潮流计算程序 BPA计算潮流 另外包含参考文献 这个程序把潮流计算的一般流程包括了,非常适合基础学习,并进一步的进行拓展创新 ,牛拉法; 电力系统潮流计算; MATLAB; BPA计算; 程序编写; 流程; 基础学习; 创新拓展,基于MATLAB的牛拉法电力系统潮流计算程序:基础学习与拓展创新指南
YOLOv11m权重文件
高一-语文-2025年1月张家界市高一期末联考-缺考不计、违纪不计、0分不计_2025-01-16-12-21 (1).zip
android kotlin 版本的贪吃蛇游戏
19考试真题最近的t57.txt
基于疫情封控区域的生活物资配送优化模型:结合遗传算法与模拟退火,实现时间最短和综合满意率最高的路径优化。,疫情下封控区域生活物资配送优化模型:结合遗传算法与模拟退火算法求解路径优化问题,实现时间与满意率双重目标优化。,模型及MATLAB代码:考充分考虑并结合疫情下封控区域生活物资配送问题及车辆路径问题的特点构建物资配送优化模型。 在一般单一目标——时间最短的基础上,加入综合满意率优化目标的路径优化问题 关键词:遗传算法、改进、模拟 火算法,路径优化、CVRP 完整模型+代码+注释 主要内容:以配送时间最短及综合满足率最高为目标,充分考虑并结合疫情下封控区域生活物资配送问题及车辆路径问题的特点构建物资配送优化模型,为疫情下生活物资配送找到了更好的思路。 在模型设计与求解问题上,首先设计标准遗传算法,继而对算法加以改进,最后设计出了改进遗传-模拟 火算法对模型进行求解。 还有参数灵敏度分析等。 服务内容:脚本 工具 部分展示如下: ,关键词:疫情下物资配送;车辆路径问题;优化模型;遗传算法;改进;模拟退火算法;CVRP;参数灵敏度分析;脚本工具;时间最短;综合满意率。 核心关键词用分号分
## 01、数据介绍 动态能力理论最早由提斯(Teece)与皮萨洛(Pisano)于1994年正式提出,他们将动态能力定义为“能够创造新产品和新过程,以及对变化的市场环境做出响应的一系列能力”。 动态能力具体体现在吸收能力、创新能力和适应能力三个方面。这些能力使公司能够快速适应市场变化,抓住新的商业机会,从而保持或提升竞争优势。 数据名称:上市公司-动态能力数据 数据年份:2012-2023年 ## 02、相关数据及指标 证券代码 证券名称 年份 Symbol RD IA ACV DC
基于ASIO的插件式服务器,支持TCP, UDP, 串口,Http, Websocket,统一化的数据接口,隔离开发人员和IO之间的操作。可以快速迭代。PSS 是针对不同 IO 逻辑的插件管理系统。您可以忽略 IO 建立的细节,构建自己的 logic 应用程序。PSS 封装了 Tcp、udp、kcp、串行端口、http、websocket 和 ssl 的统一接口。您可以使用 配置文件 或 统一接口 来创建和使用它们。logic plug-in 是完成数据到达后的 logic 处理,全部以动态库的形式加载,将 IO 和 logic 本身的耦合分开。简单的逻辑开发。本项目由三部分组成 (1) 主机(2) 数据包分析插件(3) 逻辑处理插件。您可以实现后两个插件来完成您的业务逻辑部署。
电机控制器源码:通用无感BLDC方波控制,高效参数化启动,转速达12w,环控系统一键调节,电机控制器源码:通用无感BLDC方波控制,高效调速,参数宏定义便捷调试,最高电转速达12w,电机控制器,低压无感BLDC方波控制,全部源码,方便调试移植 1.通用性极高,图片中的电机,一套参数即可启动。 2. ADC方案 3.电转速最高12w 4.电感法和普通三段式 5.按键启动和调速 6.开环,速度环,限流环 7.参数调整全部宏定义,方便调试 代码全部源码 ,电机控制器;低压无感BLDC方波控制;全部源码;通用性极高;电转速最高12w;电感法与普通三段式;按键启动调速;开环、速度环、限流环;参数调整宏定义。,通用电机控制器:低压无感BLDC方波控制源码,支持高转速12W,便捷调试移植
基于MPC的电动汽车分布式协同自适应巡航控制:上下分层控制与仿真结果展示,基于MPC的电动汽车协同自适应巡航控制:上下分层控制与仿真结果展示,基于MPC的分布式电动汽车协同自适应巡航控制,采用上下分层控制方式,上层控制器采用模型预测控制mpc方式,产生期望的加速度,下层根据期望的加速度分配扭矩;仿真结果良好,能够实现前车在加减速情况下,规划期望的跟车距离,产生期望的加速度进行自适应巡航控制。 ,关键词:MPC(模型预测控制); 分布式电动汽车; 协同自适应巡航控制; 上下分层控制方式; 期望加速度; 扭矩分配; 仿真结果良好; 前车加减速; 跟车距离。,基于MPC的分层控制电动汽车自适应巡航系统,仿真实现前车加减速跟车距离自适应
多维度购电与售电模型构建及基于CVaR与WOA优化的收益风险评估方法研究,基于CVaR风险评价及WOA优化的新型售电公司购售电模型与策略仿真研究,建立了一个电公司的购电侧模型和电侧模型,其中购电侧模型包括长期市场业务,现市场业务,可再生能源购电市场业务,分布式电源购电市场业务以及储能租赁市场业务五种类型。 电侧包括均 电价合同和实时电价合同两种类型。 然后在购电模型的基础上,提出了一种基于CVaR的购电收益风险评价方法。 根据电公司的CVaR购电收益风险数学模型,提出了一种基于WOA优化算法的新型购电收益计算方法。 该方法将购电收益风险计算公式作为WOA优化算法的目标函数,然后通过WOA的鲸鱼行走觅食、鲸鱼包围以及鲸鱼螺旋捕食三个步骤计算电公司的最优购电策略。 最后,通过MATLAB仿真工具对本文所研究的基于WOA优化的新型购电收益计算方法进行了仿真分析。 仿真结论验证了通过WOA优化算法得到的购电策略为最优购电策略。 matlab代码 仿真平台:MATLAB平台 代码具有一定的深度和创新性,注释清晰 ,关键词: 1. 购电侧模型; 2. 售电侧模型; 3. 长期/现货/可再生
迅雷软件下载原理介绍.md
## 01、数据简介 碳排放是指在人类活动中,如能源消耗、工业生产、交通运输、农业活动等过程中向大气中释放的二氧化碳等温室气体的行为。这些温室气体在大气中形成隔热层,导致地球气温升高,引发全球气候变化。分行业碳排放则是指按照不同的经济活动或产业部门来划分和统计碳排放量。 按省市县整理成面板数据,其中包括电力行业、工业过程、工业燃烧、建筑物能源、浪费、农业、燃料能源和运输八种指标排放量各省市县的最大值、最小值、平均值、总和。 数据名称:省市县分行业碳排放月度数据 数据年份:2023年 ## 02、相关数据 name 指标 时间 数值 更多数据 ## 03、数据截图