成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么阿里巴巴禁止使用Apache Beanutils進(jìn)行屬性的Copy?

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

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

[[335679]]

如我們經(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.  
  3.     private Integer id; 
  4.  
  5.     private String name
  6.  
  7.     private Integer age; 
  8.  
  9.     private Date birthday; 
  10.  
  11.     //省略setter/getter 
  12.  

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

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

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

  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用于記錄代碼執(zhí)行時(shí)間,方便進(jìn)行對(duì)比。

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

  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進(jìn)行屬性拷貝:

  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進(jìn)行屬性拷貝:

  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.  

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

  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.  

得到結(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開(kāi)源出來(lái)的的類庫(kù)性能確不高呢?這不像是Apache的風(fēng)格呀,這背后導(dǎo)致性能低下的原因又是什么呢?其實(shí),是因?yàn)锳pache BeanUtils力求做得完美, 在代碼中增加了非常多的校驗(yàn)、兼容、日志打印等代碼,過(guò)度的包裝導(dǎo)致性能下降嚴(yán)重。

總結(jié)

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

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

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

 

本文用到的第三方類庫(kù)的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. <!--日志相關(guān)--> 
  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> 

 

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專欄
相關(guān)推薦

2020-09-08 16:25:18

Apache BeancopyJava

2023-01-11 08:06:42

對(duì)象賦值項(xiàng)目開(kāi)發(fā)

2018-10-16 15:34:17

阿里巴巴Apache Flin大數(shù)據(jù)

2020-09-22 11:40:53

BigDecimalequalsJava

2021-10-11 09:32:40

包裝類型屬性

2025-04-17 08:47:23

2019-03-04 09:22:52

阿里巴巴foreach Java

2022-09-05 10:06:21

MySQL外循環(huán)內(nèi)循環(huán)

2021-08-04 17:20:30

阿里巴巴AsyncJava

2013-08-22 09:26:38

去IOE王堅(jiān)

2019-09-04 11:02:54

繼承層次組合

2019-06-26 07:54:53

ArrayListsubList源碼

2019-09-02 15:20:28

Java開(kāi)發(fā)繼承

2016-09-21 20:28:55

阿里巴巴IOE

2022-08-30 16:38:30

阿里巴巴JavaLog4j

2020-09-14 09:47:56

Java開(kāi)發(fā)類型

2019-02-27 09:00:13

阿里巴巴for循環(huán)Java

2019-01-29 10:30:32

阿里巴巴Java字符串

2021-09-07 17:22:43

阿里巴巴辭職高薪

2018-12-04 15:54:42

阿里巴巴日志系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91在线精品一区二区 | 成人欧美一区二区三区在线观看 | 成人美女免费网站视频 | 国产成人久久 | 国产在线色| 精品日韩在线 | 久久久国产一区二区三区 | 91精品国产91久久久久游泳池 | 日本成人毛片 | 亚洲区视频 | 精品一区二区免费视频 | 澳门永久av免费网站 | 日韩一级欧美一级 | 亚洲a网 | 日韩中文字幕免费 | 视频一区二区在线观看 | 国产二区三区 | 国产成人精品一区二区三区网站观看 | 黄色免费在线观看 | 狠狠色综合欧美激情 | 日韩精品区 | 久久亚洲精品国产精品紫薇 | 久久免费大片 | 国产一区亚洲二区三区 | 精品欧美二区 | 黄色网址av| 四虎影院新网址 | 日韩a级片| 国内自拍偷拍 | 男女视频在线观看网站 | 色综合久久88色综合天天 | 免费三级网站 | 亚洲精品成人 | 男女深夜网站 | 91久久久久久久久 | 91精品一区二区三区久久久久 | 国产精品久久久久久影视 | 最新中文字幕在线 | 黄视频免费观看 | 夜久久| 91欧美 |