<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 為什么禁止使用 Apache Beanutils 進行屬性的 copy ? 在日常開發中,我們經常需要給對象進行賦值,通常會調用其 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 呢? ![](https://img.kancloud.cn/c5/55/c55576bfa481ad9b2547ef5e81f0b0ed_356x46.png) 由于篇幅優先,關于這幾種工具類的用法及區別,還有到底是什么是淺拷貝和深拷貝不在本文的討論范圍內。 本文主要聚焦于對比這幾個類庫的性能問題。 性能對比 No Data No BB,我們就來寫代碼來對比下這幾種框架的性能情況。代碼示例如下: 首先定義一個 PersonDO 類: ``` public class PersonDO { private Integer id; private String name; private Integer age; private Date birthday; //省略 setter/getter } ``` 再定義一個 PersonDTO 類: ``` public class PersonDTO { private String name; private Integer age; private Date birthday; } ``` 然后進行測試類的編寫: 使用 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);? } ``` 獲得結果以下: | 工具類 | 執行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 | 畫了一張折線圖更方便你們進行對比 ![](https://img.kancloud.cn/00/ad/00ad7a4e5f463a7d0dc18e065b65c56b_480x280.png) 綜上,咱們基本能夠得出結論,在性能方面,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?PropertyUtils、Apache?BeanUtils-->?? <dependency>?? ????<groupId>commons-beanutils</groupId>?? ????<artifactId>commons-beanutils</artifactId>?? ????<version>1.9.4</version>?? </dependency>? <dependency>?? ????<groupId>commons-logging</groupId>?? ????<artifactId>commons-logging</artifactId>?? ????<version>1.1.2</version>?? </dependency>?? <!--Spring?PropertyUtils-->?? <dependency>?? ????<groupId>org.springframework</groupId>?? ????<artifactId>org.springframework.beans</artifactId>?? ????<version>3.1.1.RELEASE</version>? </dependency>?? <!--cglib-->?? <dependency>?? ????<groupId>cglib</groupId>?? ????<artifactId>cglib-nodep</artifactId>?? ????<version>2.2.2</version>?? </dependency>?? <!--dozer-->?? <dependency>?? ????<groupId>net.sf.dozer</groupId>?? ????<artifactId>dozer</artifactId>?? ????<version>5.5.1</version>?? </dependency>?? <!--日志相關-->?? <dependency>?? ????<groupId>org.slf4j</groupId>?? ????<artifactId>slf4j-api</artifactId>?? ????<version>1.7.7</version>?? </dependency>?? <dependency>? ????<groupId>org.slf4j</groupId>?? ????<artifactId>jul-to-slf4j</artifactId>?? ????<version>1.7.7</version>?? </dependency>?? <dependency>? ????<groupId>org.slf4j</groupId>?? ????<artifactId>jcl-over-slf4j</artifactId>? ????<version>1.7.7</version>?? </dependency>?? <dependency>? ????<groupId>org.slf4j</groupId>?? ????<artifactId>log4j-over-slf4j</artifactId>?? ????<version>1.7.7</version>?? </dependency>?? <dependency>?? ????<groupId>org.slf4j</groupId>?? ????<artifactId>slf4j-jdk14</artifactId>?? ????<version>1.7.7</version>?? </dependency> ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看