天天看點

Java 系統工程對象轉換 主流技術選擇是哪些?

作者:夢幻随風的網際網路筆記

Java 系統工程開發過程中,都會有各個層之間的對象轉換,比如 VO、DTO、PO、VO 等,而如果都是手動get、set又太浪費時間,還可能操作錯誤,是以選擇一個自動化工具會更加友善;

Java 系統工程對象轉換 主流技術選擇是哪些?

Spring copyProperties

org.springframework.beans.BeanUtils

這個方法是反射的屬性拷貝,Spring 提供的 copyProperties 要比 Apache 好用得多,性能和操作都比較好

BeanUtils.copyProperties(queryVo,param);           
Java 系統工程對象轉換 主流技術選擇是哪些?

裡面已經有空值校驗:

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

這是斷言,由于斷言固定抛出AssertionError異常,是以在公共方法中最好不要用,因為如果抛出異常很難辨識出這是什麼原因導緻的。

Cglib BeanCopier

org.springframework.cglib.beans.BeanCopier

的原理與Beanutils 原理不太一樣,其主要是使用 位元組碼技術動态生成一個代理類,代理類實作get 和 set方法。

生成代理類過程存在一定開銷,但是一旦生成,我們可以緩存起來重複使用,

是以 Cglib 性能相比Beanutils 性能比較好整體性能不錯,使用也不複雜

BeanCopier beanCopier = 
            BeanCopier.create(SendEnterpriseInfo.class, SalesmanEnterpriseDft.class,false);

beanCopier.copy(enterpriseDto,enterpriseDft,null);           

這裡介紹一個封裝的寫法,可以參考一下:

private        static         final       Map<BeanCopierUtil.ClassKey, BeanCopier> 
                        BEAN_COPIER_WITH_CONVERTER_CACHE 
                        = new ConcurrentHashMap();

public static BeanCopier genBeanCopierWithConverter(Object source, Object target) {
    Assert.notNull(source, "源對象不能為空");
    Assert.notNull(target, "目标對象不能為空");
    BeanCopierUtil.ClassKey classKey = buildClassKey(source, target);
    BeanCopier beanCopier = (BeanCopier)
                            BEAN_COPIER_WITH_CONVERTER_CACHE.get(classKey);
    if (beanCopier == null) {
        BeanCopier newBeanCopier = 
                             BeanCopier.create(classKey.sourceClass, classKey.targetClass, true);
        BeanCopier oldBeanCopier =
                             (BeanCopier)BEAN_COPIER_WITH_CONVERTER_CACHE.putIfAbsent(classKey, newBeanCopier);
        beanCopier = oldBeanCopier != null ? oldBeanCopier : newBeanCopier;
    }

    return beanCopier;
}           
public static BeanCopierUtil.ClassKey buildClassKey(Object source, Object target) {
    if (source != null && target != null) {
        Class<?> sourceClazz = source.getClass();
        Class<?> targetClazz = target.getClass();
        return new BeanCopierUtil.ClassKey(sourceClazz, targetClazz);
    } else {
        return null;
    }
}           
private static class ClassKey {
    private Class<?> sourceClass;
    private Class<?> targetClass;

    public ClassKey(Class<?> sourceClass, Class<?> targetClass) {
        this.sourceClass = sourceClass;
        this.targetClass = targetClass;
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        } else if (o != null && this.getClass() == o.getClass()) {
            BeanCopierUtil.ClassKey classKey = (BeanCopierUtil.ClassKey)o;
            return !Objects.equals(this.sourceClass, classKey.sourceClass) ? false : Objects.equals(this.targetClass, classKey.targetClass);
        } else {
            return false;
        }
    }

    public int hashCode() {
        int result = this.sourceClass != null ? this.sourceClass.hashCode() : 0;
        result = 31 * result + (this.targetClass != null ? this.targetClass.hashCode() : 0);
        return result;
    }
}           
Java 系統工程對象轉換 主流技術選擇是哪些?

總結: 優先使用 Cglib BeanCopier

如果你想真的了解一個原理,最好是可以把它用自己的話分享出來!

分享明智;程式和産品設計;一起交流進步!

繼續閱讀