目前流行的较为公用承认的工具类:java
Apache的两个版本:(反射机制)node
org.apache.commons.beanutils.PropertyUtils.copyProperties(Object dest, Object orig) org.apache.commons.beanutils.BeanUtils.copyProperties(Object dest, Object orig)spring
spring版本:(反射机制)apache
org.springframework.beans.BeanUtils.copyProperties(Object source, Object target, Class editable, String[] ignoreProperties)工具
cglib版本:(使用动态代理,效率高).net
net.sf.cglib.beans.BeanCopier.copy(Object paramObject1, Object paramObject2, Converter paramConverter)代理
在网上找了一个cglib的的对象copy,现记录如下,以备查找:code
package cn.qazit.common.utils;对象
import java.util.HashMap; import java.util.Map;ip
import net.sf.cglib.beans.BeanCopier;
/** *
@ClassName:CglibBeanCopierUtils.java
@Title:CglibBeanCopierUtils.java
@Description:
@CopyRight:CopyRight(c)2016
@Company:www.qazit.cn
@author ly
@date 2016年10月13日 下午5:55:01
@version:v1.0 */ public class CglibBeanCopierUtils {
public static Map<String, BeanCopier> beanCopierMap = new HashMap<String, BeanCopier>();
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包依赖
<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>