日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

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

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

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

1、Spring BeanUtils

2、Cglib BeanCopier

3、Apache BeanUtils

4、Apache PropertyUtils

5、Dozer

那么,我們到底應該選擇哪種工具類更加合適呢?為什么阿里巴巴JAVA開發手冊中提到禁止使用Apache BeanUtils呢?

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

 

?由于篇幅優先,關于這幾種工具類的用法及區別,還有到底是什么是淺拷貝和深拷貝不在本文的討論范圍內。

本文主要聚焦于對比這幾個類庫的性能問題。

性能對比

No Data No BB,我們就來寫代碼來對比下這幾種框架的性能情況。

代碼示例如下:

首先定義一個PersonDO類:

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

 

再定義一個PersonDTO類:

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

 

然后進行測試類的編寫:

使用Spring BeanUtils進行屬性拷貝:

private void mAppingBySpringBeanUtils(PersonDO personDO, int times) {

    StopWatch stopwatch = new StopWatch();

    stopwatch.start();


    for (int i = 0; i < times; i++) {

        PersonDTO personDTO = new PersonDTO();

        org.springframework.beans.BeanUtils.copyProperties(personDO, personDTO);

    }

    stopwatch.stop();

    System.out.println("mappingBySpringBeanUtils cost :" + stopwatch.getTotalTimeMillis());

}

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

使用Cglib BeanCopier進行屬性拷貝:

private void mappingByCglibBeanCopier(PersonDO personDO, int times) {

    StopWatch stopwatch = new StopWatch();

    stopwatch.start();

    for (int i = 0; i < times; i++) {

        PersonDTO personDTO = new PersonDTO();

        BeanCopier copier = BeanCopier.create(PersonDO.class, PersonDTO.class, false);

        copier.copy(personDO, personDTO, null);

    }

    stopwatch.stop();

    System.out.println("mappingByCglibBeanCopier cost :" + stopwatch.getTotalTimeMillis());

}

使用Apache BeanUtils進行屬性拷貝:

private void mappingByApacheBeanUtils(PersonDO personDO, int times)

    throws InvocationTargetException, IllegalAccessException {

    StopWatch stopwatch = new StopWatch();

    stopwatch.start();

    for (int i = 0; i < times; i++) {

        PersonDTO personDTO = new PersonDTO();

        BeanUtils.copyProperties(personDTO, personDO);

    }

    stopwatch.stop();

    System.out.println("mappingByApacheBeanUtils cost :" + stopwatch.getTotalTimeMillis());

}

使用Apache PropertyUtils進行屬性拷貝:

private void mappingByApachePropertyUtils(PersonDO personDO, int times)

    throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {

    StopWatch stopwatch = new StopWatch();

    stopwatch.start();

    for (int i = 0; i < times; i++) {

        PersonDTO personDTO = new PersonDTO();

        PropertyUtils.copyProperties(personDTO, personDO);

    }

    stopwatch.stop();

    System.out.println("mappingByApachePropertyUtils cost :" + stopwatch.getTotalTimeMillis());

}

然后執行以下代碼:

public static void main(String[] args)

    throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {

    PersonDO personDO = new PersonDO();

    personDO.setName("Hollis");

    personDO.setAge(26);

    personDO.setBirthday(new Date());

    personDO.setId(1);


    MapperTest mapperTest = new MapperTest();


    mapperTest.mappingBySpringBeanUtils(personDO, 100);

    mapperTest.mappingBySpringBeanUtils(personDO, 1000);

    mapperTest.mappingBySpringBeanUtils(personDO, 10000);

    mapperTest.mappingBySpringBeanUtils(personDO, 100000);

    mapperTest.mappingBySpringBeanUtils(personDO, 1000000);

    mapperTest.mappingByCglibBeanCopier(personDO, 100);

    mapperTest.mappingByCglibBeanCopier(personDO, 1000);

    mapperTest.mappingByCglibBeanCopier(personDO, 10000);

    mapperTest.mappingByCglibBeanCopier(personDO, 100000);

    mapperTest.mappingByCglibBeanCopier(personDO, 1000000);

    mapperTest.mappingByApachePropertyUtils(personDO, 100);

    mapperTest.mappingByApachePropertyUtils(personDO, 1000);

    mapperTest.mappingByApachePropertyUtils(personDO, 10000);

    mapperTest.mappingByApachePropertyUtils(personDO, 100000);

    mapperTest.mappingByApachePropertyUtils(personDO, 1000000);

    mapperTest.mappingByApacheBeanUtils(personDO, 100);

    mapperTest.mappingByApacheBeanUtils(personDO, 1000);

    mapperTest.mappingByApacheBeanUtils(personDO, 10000);

    mapperTest.mappingByApacheBeanUtils(personDO, 100000);

    mapperTest.mappingByApacheBeanUtils(personDO, 1000000);

}

得到結果如下:

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

 

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

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

 

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

所以,如果考慮性能情況的話,建議大家不要選擇Apache PropertyUtils、Apache BeanUtils以及Dozer等工具類。

很多人會不理解,為什么大名鼎鼎的Apache開源出來的的類庫性能卻不高呢?這不像是Apache的風格呀,這背后導致性能低下的原因又是什么呢?

其實,是因為Apache BeanUtils力求做得完美, 在代碼中增加了非常多的校驗、兼容、日志打印等代碼,過度的包裝導致性能下降嚴重。

總結

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

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

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

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

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

分享到:
標簽:阿里巴巴
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定