国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

為什么阿里巴巴禁止使用Apache Beanutils進行屬性的Copy?

開發 開發工具
在日常開發中,我們經常需要給對象進行賦值,通常會調用其set/get方法,有些時候,如果我們要轉換的兩個對象之間屬性大致相同,會考慮使用屬性拷貝工具進行。

 在日常開發中,我們經常需要給對象進行賦值,通常會調用其set/get方法,有些時候,如果我們要轉換的兩個對象之間屬性大致相同,會考慮使用屬性拷貝工具進行。

[[335679]]

如我們經常在代碼中會對一個數據結構封裝成DO、SDO、DTO、VO等,而這些Bean中的大部分屬性都是一樣的,所以使用屬性拷貝類工具可以幫助我們節省大量的set和get操作。

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

1、Spring BeanUtils

2、Cglib BeanCopier

3、Apache BeanUtils

4、Apache PropertyUtils

5、Dozer

由于篇幅優先,關于這幾種工具類的用法及區別,還有到底是什么是淺拷貝和深拷貝不在本文的討論范圍內。本文主要聚焦于對比這幾個類庫的性能問題。

性能對比

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

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

再定義一個PersonDTO類:

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

然后進行測試類的編寫:使用Spring BeanUtils進行屬性拷貝:

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

其中的StopWatch用于記錄代碼執行時間,方便進行對比。

使用Cglib BeanCopier進行屬性拷貝:

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

使用Apache BeanUtils進行屬性拷貝:

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

使用Apache PropertyUtils進行屬性拷貝:

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

然后執行以下代碼:

  1. public static void main(String[] args) 
  2.  
  3.     throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { 
  4.  
  5.     PersonDO personDO = new PersonDO(); 
  6.  
  7.     personDO.setName("Hollis"); 
  8.  
  9.     personDO.setAge(26); 
  10.  
  11.     personDO.setBirthday(new Date()); 
  12.  
  13.     personDO.setId(1); 
  14.  
  15.  
  16.     MapperTest mapperTest = new MapperTest(); 
  17.  
  18.  
  19.     mapperTest.mappingBySpringBeanUtils(personDO, 100); 
  20.  
  21.     mapperTest.mappingBySpringBeanUtils(personDO, 1000); 
  22.  
  23.     mapperTest.mappingBySpringBeanUtils(personDO, 10000); 
  24.  
  25.     mapperTest.mappingBySpringBeanUtils(personDO, 100000); 
  26.  
  27.     mapperTest.mappingBySpringBeanUtils(personDO, 1000000); 
  28.  
  29.     mapperTest.mappingByCglibBeanCopier(personDO, 100); 
  30.  
  31.     mapperTest.mappingByCglibBeanCopier(personDO, 1000); 
  32.  
  33.     mapperTest.mappingByCglibBeanCopier(personDO, 10000); 
  34.  
  35.     mapperTest.mappingByCglibBeanCopier(personDO, 100000); 
  36.  
  37.     mapperTest.mappingByCglibBeanCopier(personDO, 1000000); 
  38.  
  39.     mapperTest.mappingByApachePropertyUtils(personDO, 100); 
  40.  
  41.     mapperTest.mappingByApachePropertyUtils(personDO, 1000); 
  42.  
  43.     mapperTest.mappingByApachePropertyUtils(personDO, 10000); 
  44.  
  45.     mapperTest.mappingByApachePropertyUtils(personDO, 100000); 
  46.  
  47.     mapperTest.mappingByApachePropertyUtils(personDO, 1000000); 
  48.  
  49.     mapperTest.mappingByApacheBeanUtils(personDO, 100); 
  50.  
  51.     mapperTest.mappingByApacheBeanUtils(personDO, 1000); 
  52.  
  53.     mapperTest.mappingByApacheBeanUtils(personDO, 10000); 
  54.  
  55.     mapperTest.mappingByApacheBeanUtils(personDO, 100000); 
  56.  
  57.     mapperTest.mappingByApacheBeanUtils(personDO, 1000000); 
  58.  

得到結果如下:

工具類 執行1000次耗時 執行10000次耗時 執行100000次耗時 執行1000000次耗時
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

畫了一張折線圖更方便大家進行對比

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

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

總結

本文通過對比幾種常見的屬性拷貝的類庫,分析得出了這些工具類的性能情況,最終也驗證了《阿里巴巴Java開發手冊》中提到的"Apache BeanUtils 效率低"的事實。

但是本文只是站在性能這一單一角度進行了對比,我們在選擇一個工具類的時候還會有其他方面的考慮,比如使用成本、理解難度、兼容性、可擴展性等,對于這種拷貝類工具類,我們還會考慮其功能是否完善等。

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

 

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

  1. <!--Apache PropertyUtils、Apache BeanUtils--> 
  2.  
  3. <dependency> 
  4.  
  5.     <groupId>commons-beanutils</groupId> 
  6.  
  7.     <artifactId>commons-beanutils</artifactId> 
  8.  
  9.     <version>1.9.4</version> 
  10.  
  11. </dependency> 
  12.  
  13.  
  14.  
  15. <dependency> 
  16.  
  17.     <groupId>commons-logging</groupId> 
  18.  
  19.     <artifactId>commons-logging</artifactId> 
  20.  
  21.     <version>1.1.2</version> 
  22.  
  23. </dependency> 
  24.  
  25.  
  26.  
  27. <!--Spring PropertyUtils--> 
  28.  
  29. <dependency> 
  30.  
  31.     <groupId>org.springframework</groupId> 
  32.  
  33.     <artifactId>org.springframework.beans</artifactId> 
  34.  
  35.     <version>3.1.1.RELEASE</version> 
  36.  
  37. </dependency> 
  38.  
  39.  
  40.  
  41. <!--cglib--> 
  42.  
  43. <dependency> 
  44.  
  45.     <groupId>cglib</groupId> 
  46.  
  47.     <artifactId>cglib-nodep</artifactId> 
  48.  
  49.     <version>2.2.2</version> 
  50.  
  51. </dependency> 
  52.  
  53.  
  54.  
  55. <!--dozer--> 
  56.  
  57. <dependency> 
  58.  
  59.     <groupId>net.sf.dozer</groupId> 
  60.  
  61.     <artifactId>dozer</artifactId> 
  62.  
  63.     <version>5.5.1</version> 
  64.  
  65. </dependency> 
  66.  
  67.  
  68.  
  69. <!--日志相關--> 
  70.  
  71. <dependency> 
  72.  
  73.     <groupId>org.slf4j</groupId> 
  74.  
  75.     <artifactId>slf4j-api</artifactId> 
  76.  
  77.     <version>1.7.7</version> 
  78.  
  79. </dependency> 
  80.  
  81.  
  82.  
  83. <dependency> 
  84.  
  85.     <groupId>org.slf4j</groupId> 
  86.  
  87.     <artifactId>jul-to-slf4j</artifactId> 
  88.  
  89.     <version>1.7.7</version> 
  90.  
  91. </dependency> 
  92.  
  93.  
  94.  
  95. <dependency> 
  96.  
  97.     <groupId>org.slf4j</groupId> 
  98.  
  99.     <artifactId>jcl-over-slf4j</artifactId> 
  100.  
  101.     <version>1.7.7</version> 
  102.  
  103. </dependency> 
  104.  
  105.  
  106.  
  107. <dependency> 
  108.  
  109.     <groupId>org.slf4j</groupId> 
  110.  
  111.     <artifactId>log4j-over-slf4j</artifactId> 
  112.  
  113.     <version>1.7.7</version> 
  114.  
  115. </dependency> 
  116.  
  117.  
  118.  
  119. <dependency> 
  120.  
  121.     <groupId>org.slf4j</groupId> 
  122.  
  123.     <artifactId>slf4j-jdk14</artifactId> 
  124.  
  125.     <version>1.7.7</version> 
  126.  
  127. </dependency> 

 

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2020-09-08 16:25:18

Apache BeancopyJava

2023-01-11 08:06:42

對象賦值項目開發

2018-10-16 15:34:17

阿里巴巴Apache Flin大數據

2020-09-22 11:40:53

BigDecimalequalsJava

2021-10-11 09:32:40

包裝類型屬性

2019-03-04 09:22:52

阿里巴巴foreach Java

2025-04-17 08:47:23

2025-07-14 00:00:00

2022-09-05 10:06:21

MySQL外循環內循環

2021-08-04 17:20:30

阿里巴巴AsyncJava

2013-08-22 09:26:38

去IOE王堅

2019-09-04 11:02:54

繼承層次組合

2019-06-26 07:54:53

ArrayListsubList源碼

2019-09-02 15:20:28

Java開發繼承

2016-09-21 20:28:55

阿里巴巴IOE

2022-08-30 16:38:30

阿里巴巴JavaLog4j

2020-09-14 09:47:56

Java開發類型

2019-01-29 10:30:32

阿里巴巴Java字符串

2019-02-27 09:00:13

阿里巴巴for循環Java

2021-09-07 17:22:43

阿里巴巴辭職高薪
點贊
收藏

51CTO技術棧公眾號

高清国产福利在线观看| 色吊丝一区二区| 亚洲激情成人在线| 久久综合狠狠综合久久综青草| ririsao久久精品一区| 亚洲精品免费在线| av在线播放天堂| 国产精品资源| 国产91色在线免费| 亚洲高清影院| 亚洲成人动漫在线播放| 亚洲成人影院在线观看| 国产精品网站在线播放| 国产免费色视频| 欧美片第1页综合| 欧美与欧洲交xxxx免费观看| 免费在线观看一区| 欧美一区二区三区免费| 最猛黑人系列在线播放| 国产欧美日韩中文久久| 成人手机在线播放| 久久免费黄色| 国产超碰91| 91精品91| 成人免费自拍视频| 国产麻豆精品久久| 国产91成人video| 97青娱国产盛宴精品视频| 中文字幕欧美视频在线| 欧洲一区精品| 精品国一区二区三区| 日本电影在线观看网站| 欧美日韩国产一中文字不卡| 成人羞羞视频免费看看| 国产精品网友自拍| 国产三级三级看三级| 97久久精品人人做人人爽| 中文字幕一区二区三区有限公司| 日韩电影在线一区| 一区二区三区中文| 91福利视频在线观看| 国产精品一区二区三区四区在线观看| 亚洲欧美一区二区三区久久| 日韩另类在线| 91精品国产综合久久久久久久| 97电影在线| 欧美日韩精品高清| 精品国产白色丝袜高跟鞋| 欧美精品日日鲁夜夜添| 日本综合在线| 精品国产一区二区三区av性色| 97超碰资源站在线观看| 日韩一区二区电影在线| 中文在线аv在线| 中文字幕久精品免费视频| 99精品国自产在线| 欧美人交a欧美精品| 欧美做受69| 国产在线视频欧美| 欧美视频四区| 亚洲精品乱码久久久久久蜜桃91| 久久国产精品色| 可以在线看的av网站| 国产精品三级av在线播放| 久久久久久77777| 欧美日韩精品在线播放| 免费黄色网址在线观看| 亚洲欧美激情四射在线日| 日本精品在线播放| 国产精品午夜视频| 免费日韩av片| 三上悠亚久久精品| 亚洲人成电影网站色mp4| 精品视频二区| 精品亚洲一区二区| 激情亚洲另类图片区小说区| 成人精品视频在线| 久久国产夜色精品鲁鲁99| 欧美色图色综合| 亚洲一区中文在线| 欧洲性视频在线播放| 欧美日韩国产成人在线观看| 99久久夜色精品国产亚洲狼| 一区二区高清视频| 国产精品自在线拍| 国产精品天天狠天天看| 日日夜夜精品视频天天综合网| 国产美女网站在线观看| 黄色一区二区三区| jizz内谢中国亚洲jizz| 国产精品福利网| 久久99久久99| 性视频在线播放| 精品呦交小u女在线| 丝袜久久网站| 一区二区不卡在线观看| 亚洲成年人影院| 国产在线美女| 成人综合网网址| 久久久久久久久伊人| 在线中文字幕-区二区三区四区| 欧美激情在线观看| 久久av一区二区三区| 免费观看一二区视频网站| 亚洲欧美国产另类| 欧美视频久久| 99热99在线| 久久久久久影视| av一本在线| 久久乐国产精品| 麻豆成人综合网| 日韩电影在线观看完整版| 久久视频在线观看免费| 国产一区二区高清| 自拍偷拍第1页| 日韩中文字幕在线视频| 亚洲综合三区| 日本一区二区三区电影| 欧美成人激情图片网| 日本午夜精品一区二区三区电影 | 午夜在线视频| 久久免费福利视频| 免费在线看一区| 亚州色图欧美色图| 久久久在线免费观看| 国产激情精品久久久第一区二区| 国产免费av在线| 国产精品久久不能| 欧美国产97人人爽人人喊| 欧美国产大片| 日韩国产精品一区二区| 色婷婷av一区二区三区软件| 啄木系列成人av电影| 午夜视频在线瓜伦| 亚洲视频999| 狠狠狠色丁香婷婷综合久久五月| 国产人成网在线播放va免费| 91精品国产99久久久久久红楼 | 国产日产亚洲精品系列| 在线观看的黄色| 欧美日韩高清在线一区| 色94色欧美sute亚洲13| 日韩一区二区中文| 日本1区2区| 7777精品久久久久久| 国产午夜精品久久久久久久| 亚洲综合av一区二区三区| 91视频 - 88av| 亚洲国模精品一区| 久久精品国产亚洲一区二区三区| 18videosex性欧美麻豆| 欧美日本韩国一区二区三区| 欧美一区二区国产| 老牛嫩草一区二区三区日本| 亚洲成人三级| 日本免费高清一区| 亚洲精品一区二区在线观看| 蜜桃传媒麻豆第一区在线观看| 女同视频在线观看| 日本亚洲自拍| 精品日韩欧美在线| 喷水一区二区三区| 91丝袜在线| 国产xxxx振车| 久久亚洲国产成人| 国产免费观看久久| 日本欧美高清| 午夜在线观看视频网站| 国产精品入口免费| 精品少妇一区二区三区免费观看| 激情综合网激情| 日本免费成人| 国产精品自拍视频在线| 国产精品va在线播放| 日本高清免费不卡视频| 久久亚洲风情| 韩国精品视频在线观看| 四虎av网址| 亚洲在线免费视频| 精品美女一区二区| 成人一区二区三区在线观看 | 自拍偷拍视频在线| 中文字幕欧美视频在线| 欧美激情综合五月色丁香小说| 日韩美女精品| 大片免费播放在线视频| 欧美日韩三区四区| 在线播放日韩欧美| 亚洲人成亚洲人成在线观看图片| 在线成人直播| 波多野结衣在线观看| 欧美色图另类小说| 国产精品第8页| 欧美一区二区三区播放老司机 | 91入口在线观看| 欧美一区二区三区公司| 国产精品69久久久久水密桃| 女同久久另类99精品国产| 黄色软件在线观看| 日韩精品一区二区免费|