選擇Cglib的BeanCopier進行Bean拷貝的理由是,其性能要比Spring的BeanUtils,Apache的BeanUtils和PropertyUtils要好很多,尤其是資料量比較大的情況下。
下面看具體例子:
package com.yusj.utils;
import java.util.HashMap;
import java.util.Map;
import net.sf.cglib.beans.BeanCopier;
/**
*
* 将beancopier做成靜态類,友善拷貝
* <br>建立日期:2015年12月1日
* <br><b>Copyright 2015 UTOUU All Rights Reserved</b>
* @author yushaojian
* @since 1.0
* @version 1.0
*/
public class CglibBeanCopierUtils {
/**
*
*/
public static Map<String, BeanCopier> beanCopierMap = new HashMap<String, BeanCopier>();
/**
* @Title: copyProperties
* @Description: TODO(bean屬性轉換)
* @param source 資源類
* @param target 目标類
* @author yushaojian
* @date 2015年11月25日下午4:56:44
*/
public static void copyProperties(Object source,Object target){
String beanKey = generateKey(source.getClass(),target.getClass());
BeanCopier copier = null;
if (!beanCopierMap.containsKey(beanKey)) {
copier = BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopierMap.put(beanKey, copier);
}else {
copier = beanCopierMap.get(beanKey);
}
copier.copy(source, target, null);
}
private static String generateKey(Class<?>class1,Class<?>class2){
return class1.toString() + class2.toString();
}
/*注:
(1)相同屬性名,且類型不比對時候的處理,ok,但是未滿足的屬性不拷貝;
(2)get和set方法不比對的處理,建立拷貝的時候報錯,無法拷貝任何屬性(當且僅當sourceClass的get方法超過set方法時出現)
(3)BeanCopier
初始化例子:BeanCopier copier = BeanCopier.create(Source.class, Target.class, useConverter=true)
第三個參數userConverter,是否開啟Convert,預設BeanCopier隻會做同名,同類型屬性的copier,否則就會報錯.
copier = BeanCopier.create(source.getClass(), target.getClass(), false);
copier.copy(source, target, null);
(4)修複beanCopier對set方法強限制的限制
改寫net.sf.cglib.beans.BeanCopier.Generator.generateClass(ClassVisitor)方法
将133行的
MethodInfo write = ReflectUtils.getMethodInfo(setter.getWriteMethod());
預先存一個names2放入
109 Map names2 = new HashMap();
110 for (int i = 0; i < getters.length; ++i) {
111 names2.put(setters[i].getName(), getters[i]);
}
調用這行代碼前判斷查詢下,如果沒有改writeMethod則忽略掉該字段的操作,這樣就可以避免異常的發生。*/
}
maven依賴如下4個包:
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-commons</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-util</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.2.2</version>
</dependency>