成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

BeanUtils工具使用細(xì)節(jié)

afishhhhh / 1277人閱讀

摘要:拷貝操作又一個(gè)非常好用的工具類和中分別存在一個(gè),提供了對(duì)。除了支持基本類型以及基本類型的數(shù)組之外,還支持這些類的對(duì)象,其余一概不支持。而且,由于這些類都是采用反射機(jī)制實(shí)現(xiàn)的,對(duì)程序的效率也會(huì)有影響。因此,慎用或者使用看效果如何

java bean拷貝操作又一個(gè)非常好用的工具類 BeanUitls :
spring (org.springframework.beans.BeanUtils)和apache commons-beanutils(org.apache.commons.beanutils.BeanUtils)中分別存在一個(gè)BeanUtils,提供了對(duì)。
特別注意 這兩個(gè)類在不同的包下面,而這兩個(gè)類的copyProperties()方法里面?zhèn)鬟f的參數(shù)賦值是相反的。
例如:
a,b為對(duì)象
BeanUtils.copyProperties(a, b);

BeanUtils是org.springframework.beans.BeanUtils,
a拷貝到b
BeanUtils是org.apache.commons.beanutils.BeanUtils,
b拷貝到a

之前在寫程序時(shí),用到了兩個(gè)不同類型但屬性基本相同的對(duì)象的拷貝,由于類型不同源bean里屬性(Integer 向 int 拷貝)其值為null,這時(shí)會(huì)拋異常。

 /**
     * 測(cè)試 spring 中的 bean 拷貝
     * @throws Exception
     */
    @org.junit.Test
    public void testBeanCopy() throws Exception {
        
      PersonEntity pe = new PersonEntity();
      pe.setAge(1);
      //pe.setId(1234); // id 為 Integer 此時(shí)為null
      pe.setName("kevin");
      
      Person person = new Person(); // Person 中的id為int類型
      
      BeanUtils.copyProperties(pe, person);
      
      System.out.println(person);
        
    }

一個(gè)看似簡(jiǎn)單的問題困擾了在當(dāng)時(shí),于是抽空看了一下spring和apache commons-beanutils包中BeanUtils.copyProperties的實(shí)現(xiàn)。

spring中實(shí)現(xiàn)的方式很簡(jiǎn)單,就是對(duì)兩個(gè)對(duì)象中相同名字的屬性進(jìn)行簡(jiǎn)單get/set,僅檢查屬性的可訪問性。

源碼

package org.springframework.beans;

private static void copyProperties(Object source, Object target, Class editable, String... ignoreProperties)
            throws BeansException {

        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");

        Class actualEditable = target.getClass();
        if (editable != null) {
            if (!editable.isInstance(target)) {
                throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
                        "] not assignable to Editable class [" + editable.getName() + "]");
            }
            actualEditable = editable;
        }
        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
        List ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);

        for (PropertyDescriptor targetPd : targetPds) {
            Method writeMethod = targetPd.getWriteMethod();
            if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
                if (sourcePd != null) {
                    Method readMethod = sourcePd.getReadMethod();
                    if (readMethod != null &&
                            ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
                        try {
                            if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                                readMethod.setAccessible(true);
                            }
                            Object value = readMethod.invoke(source);
                            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                writeMethod.setAccessible(true);
                            }
                            writeMethod.invoke(target, value);
                        }
                        catch (Throwable ex) {
                            throw new FatalBeanException(
                                    "Could not copy property "" + targetPd.getName() + "" from source to target", ex);
                        }
                    }
                }
            }
        }
    }

而commons-beanutils則施加了很多的檢驗(yàn),包括類型的轉(zhuǎn)換,甚至于還會(huì)檢驗(yàn)對(duì)象所屬的類的可訪問性。

源碼

package org.apache.commons.beanutils;

public void copyProperties(Object dest, Object orig)
        throws IllegalAccessException, InvocationTargetException {

        // Validate existence of the specified beans
        if (dest == null) {
            throw new IllegalArgumentException
                    ("No destination bean specified");
        }
        if (orig == null) {
            throw new IllegalArgumentException("No origin bean specified");
        }
        if (log.isDebugEnabled()) {
            log.debug("BeanUtils.copyProperties(" + dest + ", " +
                      orig + ")");
        }

        // Copy the properties, converting as necessary
        if (orig instanceof DynaBean) {
            DynaProperty origDescriptors[] =
                ((DynaBean) orig).getDynaClass().getDynaProperties();
            for (int i = 0; i < origDescriptors.length; i++) {
                String name = origDescriptors[i].getName();
                if (getPropertyUtils().isWriteable(dest, name)) {
                    Object value = ((DynaBean) orig).get(name);
                    copyProperty(dest, name, value);
                }
            }
        } else if (orig instanceof Map) {
            Iterator names = ((Map) orig).keySet().iterator();
            while (names.hasNext()) {
                String name = (String) names.next();
                if (getPropertyUtils().isWriteable(dest, name)) {
                    Object value = ((Map) orig).get(name);
                    copyProperty(dest, name, value);
                }
            }
        } else /* if (orig is a standard JavaBean) */ {
            PropertyDescriptor origDescriptors[] =
                getPropertyUtils().getPropertyDescriptors(orig);
            for (int i = 0; i < origDescriptors.length; i++) {
                String name = origDescriptors[i].getName();
                if ("class".equals(name)) {
                    continue; // No point in trying to set an object"s class
                }
                if (getPropertyUtils().isReadable(orig, name) &&
                    getPropertyUtils().isWriteable(dest, name)) {
                    try {
                        Object value =
                            getPropertyUtils().getSimpleProperty(orig, name);
                        copyProperty(dest, name, value);
                    } catch (NoSuchMethodException e) {
                        ; // Should not happen
                    }
                }
            }
        }

    }

而且,commons-beanutils中的裝換是不支持java.util.Date的。除了支持基本類型以及基本類型的數(shù)組之外,還支持java.sql.Date, java.sql.Time, java.sql.TimeStamp, java.io.File, javaio.URL這些類的對(duì)象,其余一概不支持。不過你可以自定義你的類的Converter。然后注冊(cè)進(jìn)去。所以在使用時(shí)

感覺commons-beanutils包中的這個(gè)BeanUtils類的copyProperties方法,太過復(fù)雜,約束太多,而且使用不便,雖然可擴(kuò)展性好了,但是易用性不高。

總結(jié):

關(guān)于bean復(fù)制,如果屬性較少,建議直接寫個(gè)方法完成get/set即可。如果屬性較多,可以自己采用反射實(shí)現(xiàn)一個(gè)滿足自己需要的工具類,或者使用spring的那個(gè)beanutils類,不建議使用commons-beanutils包中的那個(gè)BeanUtils類,剛看了下,這個(gè)類對(duì)于內(nèi)部靜態(tài)類的對(duì)象復(fù)制也會(huì)出現(xiàn)問題,檢驗(yàn)太復(fù)雜了,常會(huì)出現(xiàn)一些詭異的問題。畢竟我們bean復(fù)制一般就是簡(jiǎn)單的屬性copy而已。

而且,由于這些BeanUtils類都是采用反射機(jī)制實(shí)現(xiàn)的,對(duì)程序的效率也會(huì)有影響。因此,慎用BeanUtils.copyProperties?。。』蛘呤褂胏lone看效果如何!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/35799.html

相關(guān)文章

  • 徒手?jǐn)]框架--實(shí)現(xiàn)IoC

    摘要:從而能夠進(jìn)一步深入了解框架。至此我們框架開發(fā)完成。雖然說閱讀源碼是了解框架的最終手段。但是框架作為一個(gè)生產(chǎn)框架,為了保證通用和穩(wěn)定,源碼必定是高度抽象,且處理大量細(xì)節(jié)。下一篇文章應(yīng)該會(huì)是徒手?jǐn)]框架實(shí)現(xiàn)。 原文地址:https://www.xilidou.com/2018/... Spring 作為 J2ee 開發(fā)事實(shí)上的標(biāo)準(zhǔn),是每個(gè)Java開發(fā)人員都需要了解的框架。但是Spring 的...

    rottengeek 評(píng)論0 收藏0
  • Java BeanUtils對(duì)象復(fù)制工具類及方法

    1. BeanUtils.copyProperties(Object source, Object target) 用法: 講source的屬性值復(fù)制到target,屬性為null時(shí)也會(huì)進(jìn)行復(fù)制。 需求:排除null值進(jìn)行復(fù)制 public class CopyObjectUtil { public static String[] getNullPropertyNames(Object...

    Kerr1Gan 評(píng)論0 收藏0
  • 為什么阿里代碼規(guī)約要求避免使用 Apache BeanUtils 進(jìn)行屬性的拷貝

    摘要:于是我建議這位小伙伴使用了進(jìn)行屬性拷貝,這為我們的程序挖了一個(gè)坑阿里代碼規(guī)約當(dāng)我們開啟阿里代碼掃描插件時(shí),如果你使用了進(jìn)行屬性拷貝,它會(huì)給你一個(gè)非常嚴(yán)重的警告。大名鼎鼎的提供的包,居然會(huì)存在性能問題,以致于阿里給出了嚴(yán)重的警告。 聲明:本文屬原創(chuàng)文章,始發(fā)于公號(hào):程序員自學(xué)之道,并同步發(fā)布于 https://blog.csdn.net/dadiyang,特此,同步發(fā)布到 sf,轉(zhuǎn)載請(qǐng)注...

    raledong 評(píng)論0 收藏0
  • 接口間參數(shù)傳遞的一種解決方案

    摘要:解決鏈路間參數(shù)傳遞的問題可以簡(jiǎn)化為解決接口間的參數(shù)傳遞問題。當(dāng)然,針對(duì)這個(gè)問題的解決方案,其實(shí)還是蠻多的。總結(jié)下來,自動(dòng)化用例的維護(hù)和開發(fā)成本主要集中在接口間參數(shù)傳遞的維護(hù)上面。 引言 做過接口自動(dòng)化測(cè)試的同學(xué)肯定都熟悉在全鏈路測(cè)試過程中,很多業(yè)務(wù)場(chǎng)景的完成并非由單一接口實(shí)現(xiàn),而是由很多接...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • 使用JMH對(duì)比BeanUtils和BeanCopier

    摘要:背景許多時(shí)候需要對(duì)比不同的框架或工具或算法,選擇使用性能更優(yōu)的那一個(gè)。通常的做法是但這樣的做法非常不嚴(yán)謹(jǐn),因?yàn)楫?dāng)獨(dú)立頻繁運(yùn)行這一小塊代碼時(shí),可能會(huì)針對(duì)性的做一些優(yōu)化工作,而在實(shí)際的生產(chǎn)環(huán)境中是不會(huì)有此優(yōu)化的。 背景 許多時(shí)候需要對(duì)比不同的框架或工具或算法, 選擇使用性能更優(yōu)的那一個(gè)。通常的做法是 long start = System.currentTimeMillis(); for(...

    yuxue 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<