代码
package com.gdpu.util;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import net.sf.cglib.beans.BeanCopier;
import net.sf.cglib.core.Converter;
import org.apache.commons.lang3.ClassUtils;
/**
* @author mojiazhu
* @date 2022/12/11 21:52
*/
public class BeanCopyUtil {
/**
* beancopier map,缓存已创建的beancopier,避免重复创建,使用ConcurrentMap,保证线程安全 final对象非基本类型时,引用恒定不变,不可修改,但对象本身可被修改
*/
private final static ConcurrentMap<String, BeanCopier> BEAN_COPIERS = new ConcurrentHashMap<>();
/**
* NestedObjectConverter map,缓存已创建的NestedObjectConverter,避免重复创建
*/
private final static ConcurrentMap<String, NestedObjectConverter> NESTED_OBJECT_CONVERTER_CONCURRENT_MAP
= new ConcurrentHashMap<>();
/**
* 集合copy,将输入集合拷贝至输出集合
*
* @param srcColl 输入集合
* @param dstColl 输出集合
* @param dstClazz 输出集合中的对象类型
* @return 输出集合
*/
public static <T1 extends Collection<?>, T2 extends Collection<T3>, T3> T2 copyList(
T1 srcColl, T2 dstColl, Class<T3> dstClazz) {
if (srcColl == null || dstColl == null || dstClazz == null) {
throw new NullPointerException("Param cannot be null!");
}
try {
for (Object srcObj : srcColl) {
T3 dstObj = dstClazz.newInstance();
dstColl.add(copy(srcObj, dstObj));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return dstColl;
}
/**
* 集合深copy,将输入集合拷贝至输出集合
*
* @param srcColl 输入集合
* @param dstColl 输出集合
* @param dstClazz 输出集合中的对象类型
* @return 输出集合
*/
@SuppressWarnings("unchecked")
private static Collection deepCopyColl(Collection srcColl, Collection dstColl, Class dstClazz)
throws NullPointerException, InstantiationException, IllegalAccessException {
if (srcColl == null || dstColl == null || dstClazz == null) {
throw new NullPointerException("Param cannot be null!");
}
for (Object srcObj : srcColl) {
Object dstObj;
if (!ClassUtils.isPrimitiveOrWrapper(dstClazz)) {
dstObj = dstClazz.newInstance();
NestedObjectConverter nestedObjectConverter = getNestedObjectConverter(dstObj.getClass());
copyWithConverter(srcObj, dstObj, nestedObjectConverter);
} else {
dstObj = srcObj;
}
dstColl.add(dstObj);
}
return dstColl;
}
/**
* 对象Copy
*
* @param src 源对象
* @param dst 目标对象
* @return 目标对象
*/
public static <T1, T2> T2 copy(T1 src, T2 dst) {
BeanCopier beanCopier = getBeanCopier(src, dst, false);
beanCopier.copy(src, dst, null);
return dst;
}
/**
* 深拷贝,支持类中嵌套有复杂对象的拷贝
*
* @param src 源对象
* @param dst 目标对象
* @return 目标对象
*/
public static <T1, T2> T2 deepCopy(T1 src, T2 dst) {
BeanCopier beanCopier = getBeanCopier(src, dst, true);
NestedObjectConverter nestedObjectConverter = getNestedObjectConverter(dst.getClass());
beanCopier.copy(src, dst, nestedObjectConverter);
return dst;
}
/**
* 带转换类的对象Copy
*
* @param src 源对象
* @param dst 目标对象
* @return 目标对象
*/
private static <T1, T2> T2 copyWithConverter(T1 src, T2 dst, Converter converter) {
BeanCopier beanCopier = getBeanCopier(src, dst, true);
beanCopier.copy(src, dst, converter);
return dst;
}
/**
* 获取BeanCopier对象,不存在则创建
*
* @param src 源对象
* @param dst 目标对象
* @return BeanCopier对象
*/
private static BeanCopier getBeanCopier(Object src, Object dst, boolean hasConverter) {
if (src == null || dst == null) {
throw new NullPointerException("Param cannot be null!");
}
String srcClassName = src.getClass().getName();
String dstClassName = dst.getClass().getName();
String key = srcClassName + "," + dstClassName + "," + String.valueOf(hasConverter);
if (!BEAN_COPIERS.containsKey(key)) {
BeanCopier beanCopier = BeanCopier.create(src.getClass(), dst.getClass(), hasConverter);
BEAN_COPIERS.putIfAbsent(key, beanCopier);
}
return BEAN_COPIERS.get(key);
}
/**
* 获取嵌套类转换器,不存在则创建
*
* @param enclosingClazz 外部类
* @return 嵌套类转换器
*/
private static NestedObjectConverter getNestedObjectConverter(Class enclosingClazz) {
if (enclosingClazz == null) {
throw new NullPointerException("Param cannot be null!");
}
if (!NESTED_OBJECT_CONVERTER_CONCURRENT_MAP.containsKey(enclosingClazz.getName())) {
NestedObjectConverter nestedObjectConverter = new NestedObjectConverter(enclosingClazz);
NESTED_OBJECT_CONVERTER_CONCURRENT_MAP.putIfAbsent(enclosingClazz.getName(), nestedObjectConverter);
}
return NESTED_OBJECT_CONVERTER_CONCURRENT_MAP.get(enclosingClazz.getName());
}
/**
* 嵌套对象转换,支持原类和目标类中存在同名的非基础类型或基础类型包装类型的属性的转换 容器类型仅支持ArrayList类型属性的转换
*/
private static class NestedObjectConverter implements Converter {
private Class enclosingClass;
NestedObjectConverter(Class enclosingClass) {
this.enclosingClass = enclosingClass;
}
@Override
public Object convert(Object o, Class aClass, Object o1) {
if (o == null || ClassUtils.isPrimitiveOrWrapper(aClass) || o instanceof String) {
return o;
}
// 如果源对象的类为数组类,执行集合拷贝
try {
if (Collection.class.isAssignableFrom(o.getClass())) {
Method[] methods = enclosingClass.getMethods();
for (Method m : methods) {
if (m.getName().equals(o1) && Collection.class.isAssignableFrom(m.getParameterTypes()[0])) {
Collection dstColl = (Collection) o.getClass().newInstance();
return deepCopyColl((Collection) o, dstColl, getGenericSetMethodParameterType(m));
}
}
}
// 非集合类执行普通拷贝
else {
Object dst = aClass.newInstance();
return deepCopy(o, dst);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return null;
}
/**
* 获得set方法参数的泛型类型
*
* @param setMethod set方法
* @return 泛型类型
*/
private Class getGenericSetMethodParameterType(Method setMethod) {
Type genericParameterType = setMethod.getGenericParameterTypes()[0];
if (genericParameterType instanceof ParameterizedType) {
ParameterizedType type = (ParameterizedType) genericParameterType;
return (Class) type.getActualTypeArguments()[0];
}
return null;
}
}
}
使用
复制对象
复制集合
依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.6</version>
</dependency>