日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
為什么阿里巴巴禁止使用ApacheBeanutils進(jìn)行屬性的Copy?

 在日常開發(fā)中,我們經(jīng)常需要給對(duì)象進(jìn)行賦值,通常會(huì)調(diào)用其set/get方法,有些時(shí)候,如果我們要轉(zhuǎn)換的兩個(gè)對(duì)象之間屬性大致相同,會(huì)考慮使用屬性拷貝工具進(jìn)行。

創(chuàng)新互聯(lián)是一家專業(yè)提供陵川企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司H5開發(fā)、小程序制作等業(yè)務(wù)。10年已為陵川眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進(jìn)行中。

如我們經(jīng)常在代碼中會(huì)對(duì)一個(gè)數(shù)據(jù)結(jié)構(gòu)封裝成DO、SDO、DTO、VO等,而這些Bean中的大部分屬性都是一樣的,所以使用屬性拷貝類工具可以幫助我們節(jié)省大量的set和get操作。

市面上有很多類似的工具類,比較常用的有

1、Spring BeanUtils

2、Cglib BeanCopier

3、Apache BeanUtils

4、Apache PropertyUtils

5、Dozer

由于篇幅優(yōu)先,關(guān)于這幾種工具類的用法及區(qū)別,還有到底是什么是淺拷貝和深拷貝不在本文的討論范圍內(nèi)。本文主要聚焦于對(duì)比這幾個(gè)類庫(kù)的性能問(wèn)題。

性能對(duì)比

No Data No BB,我們就來(lái)寫代碼來(lái)對(duì)比下這幾種框架的性能情況。代碼示例如下:首先定義一個(gè)PersonDO類:

 
 
 
 
  1. public class PersonDO {
  2.     private Integer id;
  3.     private String name;
  4.     private Integer age;
  5.     private Date birthday;
  6.     //省略setter/getter
  7. }

再定義一個(gè)PersonDTO類:

 
 
 
 
  1. public class PersonDTO {
  2.     private String name;
  3.     private Integer age;
  4.     private Date birthday;
  5. }

然后進(jìn)行測(cè)試類的編寫:使用Spring BeanUtils進(jìn)行屬性拷貝:

 
 
 
 
  1. private void mappingBySpringBeanUtils(PersonDO personDO, int times) {
  2.     StopWatch stopwatch = new StopWatch();
  3.     stopwatch.start();
  4.     for (int i = 0; i < times; i++) {
  5.         PersonDTO personDTO = new PersonDTO();
  6.         org.springframework.beans.BeanUtils.copyProperties(personDO, personDTO);
  7.     }
  8.     stopwatch.stop();
  9.     System.out.println("mappingBySpringBeanUtils cost :" + stopwatch.getTotalTimeMillis());
  10. }

其中的StopWatch用于記錄代碼執(zhí)行時(shí)間,方便進(jìn)行對(duì)比。

使用Cglib BeanCopier進(jìn)行屬性拷貝:

 
 
 
 
  1. private void mappingByCglibBeanCopier(PersonDO personDO, int times) {
  2.     StopWatch stopwatch = new StopWatch();
  3.     stopwatch.start();
  4.     for (int i = 0; i < times; i++) {
  5.         PersonDTO personDTO = new PersonDTO();
  6.         BeanCopier copier = BeanCopier.create(PersonDO.class, PersonDTO.class, false);
  7.         copier.copy(personDO, personDTO, null);
  8.     }
  9.     stopwatch.stop();
  10.     System.out.println("mappingByCglibBeanCopier cost :" + stopwatch.getTotalTimeMillis());
  11. }

使用Apache BeanUtils進(jìn)行屬性拷貝:

 
 
 
 
  1. private void mappingByApacheBeanUtils(PersonDO personDO, int times)
  2.     throws InvocationTargetException, IllegalAccessException {
  3.     StopWatch stopwatch = new StopWatch();
  4.     stopwatch.start();
  5.     for (int i = 0; i < times; i++) {
  6.         PersonDTO personDTO = new PersonDTO();
  7.         BeanUtils.copyProperties(personDTO, personDO);
  8.     }
  9.     stopwatch.stop();
  10.     System.out.println("mappingByApacheBeanUtils cost :" + stopwatch.getTotalTimeMillis());
  11. }

使用Apache PropertyUtils進(jìn)行屬性拷貝:

 
 
 
 
  1. private void mappingByApachePropertyUtils(PersonDO personDO, int times)
  2.     throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
  3.     StopWatch stopwatch = new StopWatch();
  4.     stopwatch.start();
  5.     for (int i = 0; i < times; i++) {
  6.         PersonDTO personDTO = new PersonDTO();
  7.         PropertyUtils.copyProperties(personDTO, personDO);
  8.     }
  9.     stopwatch.stop();
  10.     System.out.println("mappingByApachePropertyUtils cost :" + stopwatch.getTotalTimeMillis());
  11. }

然后執(zhí)行以下代碼:

 
 
 
 
  1. public static void main(String[] args)
  2.     throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
  3.     PersonDO personDO = new PersonDO();
  4.     personDO.setName("Hollis");
  5.     personDO.setAge(26);
  6.     personDO.setBirthday(new Date());
  7.     personDO.setId(1);
  8.     MapperTest mapperTest = new MapperTest();
  9.     mapperTest.mappingBySpringBeanUtils(personDO, 100);
  10.     mapperTest.mappingBySpringBeanUtils(personDO, 1000);
  11.     mapperTest.mappingBySpringBeanUtils(personDO, 10000);
  12.     mapperTest.mappingBySpringBeanUtils(personDO, 100000);
  13.     mapperTest.mappingBySpringBeanUtils(personDO, 1000000);
  14.     mapperTest.mappingByCglibBeanCopier(personDO, 100);
  15.     mapperTest.mappingByCglibBeanCopier(personDO, 1000);
  16.     mapperTest.mappingByCglibBeanCopier(personDO, 10000);
  17.     mapperTest.mappingByCglibBeanCopier(personDO, 100000);
  18.     mapperTest.mappingByCglibBeanCopier(personDO, 1000000);
  19.     mapperTest.mappingByApachePropertyUtils(personDO, 100);
  20.     mapperTest.mappingByApachePropertyUtils(personDO, 1000);
  21.     mapperTest.mappingByApachePropertyUtils(personDO, 10000);
  22.     mapperTest.mappingByApachePropertyUtils(personDO, 100000);
  23.     mapperTest.mappingByApachePropertyUtils(personDO, 1000000);
  24.     mapperTest.mappingByApacheBeanUtils(personDO, 100);
  25.     mapperTest.mappingByApacheBeanUtils(personDO, 1000);
  26.     mapperTest.mappingByApacheBeanUtils(personDO, 10000);
  27.     mapperTest.mappingByApacheBeanUtils(personDO, 100000);
  28.     mapperTest.mappingByApacheBeanUtils(personDO, 1000000);
  29. }

得到結(jié)果如下:

工具類 執(zhí)行1000次耗時(shí) 執(zhí)行10000次耗時(shí) 執(zhí)行100000次耗時(shí) 執(zhí)行1000000次耗時(shí)
Spring BeanUtils 5ms 10ms 45ms 169ms
Cglib BeanCopier 4ms 18ms 45ms 91ms
Apache PropertyUtils 60ms 265ms 1444ms 11492ms
Apache BeanUtils 138ms 816ms 4154ms 36938ms
Dozer 566ms 2254ms 11136ms 102965ms

畫了一張折線圖更方便大家進(jìn)行對(duì)比

綜上,我們基本可以得出結(jié)論,在性能方面,Spring BeanUtils和Cglib BeanCopier表現(xiàn)比較不錯(cuò),而Apache PropertyUtils、Apache BeanUtils以及Dozer則表現(xiàn)的很不好。

所以,如果考慮性能情況的話,建議大家不要選擇Apache PropertyUtils、Apache BeanUtils以及Dozer等工具類。很多人會(huì)不理解,為什么大名鼎鼎的Apache開源出來(lái)的的類庫(kù)性能確不高呢?這不像是Apache的風(fēng)格呀,這背后導(dǎo)致性能低下的原因又是什么呢?其實(shí),是因?yàn)锳pache BeanUtils力求做得完美, 在代碼中增加了非常多的校驗(yàn)、兼容、日志打印等代碼,過(guò)度的包裝導(dǎo)致性能下降嚴(yán)重。

總結(jié)

本文通過(guò)對(duì)比幾種常見的屬性拷貝的類庫(kù),分析得出了這些工具類的性能情況,最終也驗(yàn)證了《阿里巴巴Java開發(fā)手冊(cè)》中提到的"Apache BeanUtils 效率低"的事實(shí)。

但是本文只是站在性能這一單一角度進(jìn)行了對(duì)比,我們?cè)谶x擇一個(gè)工具類的時(shí)候還會(huì)有其他方面的考慮,比如使用成本、理解難度、兼容性、可擴(kuò)展性等,對(duì)于這種拷貝類工具類,我們還會(huì)考慮其功能是否完善等。

就像雖然Dozer性能比較差,但是他可以很好的和Spring結(jié)合,可以通過(guò)配置文件等進(jìn)行屬性之間的映射等,也受到了很多開發(fā)者的喜愛。

本文用到的第三方類庫(kù)的maven依賴如下:

 
 
 
 
  1.     commons-beanutils
  2.     commons-beanutils
  3.     1.9.4
  4.     commons-logging
  5.     commons-logging
  6.     1.1.2
  7.     org.springframework
  8.     org.springframework.beans
  9.     3.1.1.RELEASE
  10.     cglib
  11.     cglib-nodep
  12.     2.2.2
  13.     net.sf.dozer
  14.     dozer
  15.     5.5.1
  16.     org.slf4j
  17.     slf4j-api
  18.     1.7.7
  19.     org.slf4j
  20.     jul-to-slf4j
  21.     1.7.7
  22.     org.slf4j
  23.     jcl-over-slf4j
  24.     1.7.7
  25.     org.slf4j
  26.     log4j-over-slf4j
  27.     1.7.7
  28.     org.slf4j
  29.     slf4j-jdk14
  30.     1.7.7

分享文章:為什么阿里巴巴禁止使用ApacheBeanutils進(jìn)行屬性的Copy?
分享路徑:http://www.dlmjj.cn/article/djdhies.html