為什么阿里巴巴禁止使用Apache Beanutils進(jìn)行屬性的copy?
點(diǎn)擊上方?好好學(xué)java?,選擇?星標(biāo)?公眾號(hào)
重磅資訊,干貨,第一時(shí)間送達(dá) 今日推薦:分享一套基于SpringBoot和Vue的企業(yè)級(jí)中后臺(tái)開(kāi)源項(xiàng)目,這個(gè)項(xiàng)目有點(diǎn)哇塞!
個(gè)人原創(chuàng)100W +訪問(wèn)量博客:點(diǎn)擊前往,查看更多
在日常開(kāi)發(fā)中,我們經(jīng)常需要給對(duì)象進(jìn)行賦值,通常會(huì)調(diào)用其set/get方法,有些時(shí)候,如果我們要轉(zhuǎn)換的兩個(gè)對(duì)象之間屬性大致相同,會(huì)考慮使用屬性拷貝工具進(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īng)該選擇哪種工具類更加合適呢?為什么阿里巴巴Java開(kāi)發(fā)手冊(cè)中提到禁止使用Apache BeanUtils呢?

由于篇幅優(yōu)先,關(guān)于這幾種工具類的用法及區(qū)別,還有到底是什么是淺拷貝和深拷貝不在本文的討論范圍內(nèi)。
本文主要聚焦于對(duì)比這幾個(gè)類庫(kù)的性能問(wèn)題。
性能對(duì)比
No Data No BB,我們就來(lái)寫(xiě)代碼來(lái)對(duì)比下這幾種框架的性能情況。
代碼示例如下:
首先定義一個(gè)PersonDO類:
public?class?PersonDO?{
????private?Integer?id;
????private?String?name;
????private?Integer?age;
????private?Date?birthday;
????//省略setter/getter
}
再定義一個(gè)PersonDTO類:
public?class?PersonDTO?{
????private?String?name;
????private?Integer?age;
????private?Date?birthday;
}
然后進(jìn)行測(cè)試類的編寫(xiě):
使用Spring BeanUtils進(jìn)行屬性拷貝:
private?void?mappingBySpringBeanUtils(PersonDO?personDO,?int?times)?{
????StopWatch?stopwatch?=?new?StopWatch();
????stopwatch.start();
????for?(int?i?=?0;?i?
????????PersonDTO?personDTO?=?new?PersonDTO();
????????org.springframework.beans.BeanUtils.copyProperties(personDO,?personDTO);
????}
????stopwatch.stop();
????System.out.println("mappingBySpringBeanUtils?cost?:"?+?stopwatch.getTotalTimeMillis());
}
private?void?mappingByCglibBeanCopier(PersonDO?personDO,?int?times)?{
????StopWatch?stopwatch?=?new?StopWatch();
????stopwatch.start();
????for?(int?i?=?0;?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());
}
private?void?mappingByApacheBeanUtils(PersonDO?personDO,?int?times)
????throws?InvocationTargetException,?IllegalAccessException?{
????StopWatch?stopwatch?=?new?StopWatch();
????stopwatch.start();
????for?(int?i?=?0;?i?
????????PersonDTO?personDTO?=?new?PersonDTO();
????????BeanUtils.copyProperties(personDTO,?personDO);
????}
????stopwatch.stop();
????System.out.println("mappingByApacheBeanUtils?cost?:"?+?stopwatch.getTotalTimeMillis());
}
private?void?mappingByApachePropertyUtils(PersonDO?personDO,?int?times)
????throws?InvocationTargetException,?IllegalAccessException,?NoSuchMethodException?{
????StopWatch?stopwatch?=?new?StopWatch();
????stopwatch.start();
????for?(int?i?=?0;?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);
}

<dependency>
????<groupId>commons-beanutilsgroupId>
????<artifactId>commons-beanutilsartifactId>
????<version>1.9.4version>
dependency>
<dependency>
????<groupId>commons-logginggroupId>
????<artifactId>commons-loggingartifactId>
????<version>1.1.2version>
dependency>
<dependency>
????<groupId>org.springframeworkgroupId>
????<artifactId>org.springframework.beansartifactId>
????<version>3.1.1.RELEASEversion>
dependency>
<dependency>
????<groupId>cglibgroupId>
????<artifactId>cglib-nodepartifactId>
????<version>2.2.2version>
dependency>
<dependency>
????<groupId>net.sf.dozergroupId>
????<artifactId>dozerartifactId>
????<version>5.5.1version>
dependency>
<dependency>
????<groupId>org.slf4jgroupId>
????<artifactId>slf4j-apiartifactId>
????<version>1.7.7version>
dependency>
<dependency>
????<groupId>org.slf4jgroupId>
????<artifactId>jul-to-slf4jartifactId>
????<version>1.7.7version>
dependency>
<dependency>
????<groupId>org.slf4jgroupId>
????<artifactId>jcl-over-slf4jartifactId>
????<version>1.7.7version>
dependency>
<dependency>
????<groupId>org.slf4jgroupId>
????<artifactId>log4j-over-slf4jartifactId>
????<version>1.7.7version>
dependency>
<dependency>
????<groupId>org.slf4jgroupId>
????<artifactId>slf4j-jdk14artifactId>
????<version>1.7.7version>
dependency>
推薦文章
分享一套基于SpringBoot和Vue的企業(yè)級(jí)中后臺(tái)開(kāi)源項(xiàng)目,這個(gè)項(xiàng)目有點(diǎn)哇塞!
圈子哥推薦一種基于Spring Boot開(kāi)發(fā)OA開(kāi)源產(chǎn)品,學(xué)習(xí)/搞外快都是不二選擇!
原創(chuàng)電子書(shū)
歷時(shí)整整一年總結(jié)的?Java面試+ Java入門技術(shù)學(xué)習(xí)指南,這是本人這幾年及校招的總結(jié),各種異步面試題已經(jīng)全部進(jìn)行總結(jié),按照章節(jié)復(fù)習(xí)即可,已經(jīng)拿到了了大廠提供。 原創(chuàng)思維導(dǎo)圖
掃碼或者微信搜?程序員的技術(shù)圈子?回復(fù)?面試?領(lǐng)取原創(chuàng)電子書(shū)和思維導(dǎo)圖。



