package com.panzhihua.common.utlis; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.util.StringUtils; import com.alibaba.fastjson.JSONObject; import com.esotericsoftware.reflectasm.MethodAccess; import cn.hutool.core.bean.BeanUtil; import lombok.extern.slf4j.Slf4j; /** * 通用情况拷贝 * * @author tkq * @date 14:36 2019/4/10 */ @Slf4j public class CopyUtil { private static final Logger logger = LoggerFactory.getLogger(CopyUtil.class); @SuppressWarnings("rawtypes") private static Map methodMap = new ConcurrentHashMap<>(); private static Map methodIndexMap = new ConcurrentHashMap<>(); @SuppressWarnings("rawtypes") private static Map> fieldMap = new ConcurrentHashMap<>(); private CopyUtil() { } /** *

* 对数组进行拷贝 *

* * @author tkq * @date 2018年12月19日 */ public static List copyList(List desc, Class targetClass) { if (desc == null) { return new ArrayList<>(); } if (desc.isEmpty()) { return new ArrayList<>(); } // 创建返回对象 List targetList = new ArrayList<>(desc.size()); for (Object des : desc) { if (null != des) { try { T newInstance = targetClass.newInstance(); copyProperties(des, newInstance); targetList.add(newInstance); } catch (InstantiationException | IllegalAccessException e) { logger.error(e.getMessage(), e); } } } return targetList; } /** *

* 对数组进行拷贝 *

* * @author manailin * @date 2018年12月19日 */ public static List beanCopyList(List desc, Class targetClass) { if (desc == null) { return new ArrayList<>(); } if (desc.isEmpty()) { return new ArrayList<>(); } // 创建返回对象 List targetList = new ArrayList<>(desc.size()); for (Object des : desc) { if (null != des) { try { T newInstance = targetClass.newInstance(); BeanUtil.copyProperties(des, newInstance); targetList.add(newInstance); } catch (InstantiationException | IllegalAccessException e) { logger.error(e.getMessage(), e); } } } return targetList; } /** * @Title: * @Description: 根据目标对象类型进行拷贝 * @author tkq * @date:2019/1/2 * @Copyright: 2018 All rights reserved. 注意:禁止外泄以及用于其他的商业目 */ public static T copyPropertiesByClass(Object desc, Class targetClass) { if (desc != null) { try { T newInstance = targetClass.newInstance(); copyProperties(desc, newInstance); return newInstance; } catch (Exception e) { logger.error(e.getMessage(), e); } } return null; } /** * 进行复制方法 * * @param dataSource * 源目标对象 * @param target * 目标对象 * @author tkq * @date 14:37 2019-11-13 */ public static void copyProperties(Object dataSource, Object target) { if (target == null) { return; } if (dataSource == null) { return; } MethodAccess descMethodAccess = methodMap.get(target.getClass()); if (descMethodAccess == null) { descMethodAccess = cache(target); } MethodAccess orgiMethodAccess = methodMap.get(dataSource.getClass()); if (orgiMethodAccess == null) { orgiMethodAccess = cache(dataSource); } List fieldList = fieldMap.get(dataSource.getClass()); for (String field : fieldList) { String getKey = dataSource.getClass().getName() + "." + "get" + field; String setkey = target.getClass().getName() + "." + "set" + field; Integer setIndex = methodIndexMap.get(setkey); if (setIndex != null) { int getIndex = methodIndexMap.get(getKey); // 参数一需要反射的对象 // 参数二class.getDeclaredMethods 对应方法的index // 参数对三象集合 try { descMethodAccess.invoke(target, setIndex.intValue(), orgiMethodAccess.invoke(dataSource, getIndex)); } catch (Exception e) { log.info("field:" + field); throw e; } } } } /** * 单例模式 * * @param object * 实体对象 * @return MethodAccess * @author tkq * @date 14:36 2019/4/10 */ private static MethodAccess cache(Object object) { Class name = object.getClass(); synchronized (name) { MethodAccess methodAccess = MethodAccess.get(name); Class className = object.getClass(); Set fields = new HashSet<>(); for (; className != Object.class; className = className.getSuperclass()) { fields.addAll(Arrays.asList(className.getDeclaredFields())); } List fieldList = new ArrayList<>(fields.size()); for (Field field : fields) { // 是否是私有的,是否是静态的 if (Modifier.isPrivate(field.getModifiers()) && !Modifier.isStatic(field.getModifiers())) { // 非公共私有变量 // 获取属性名称 String fieldName = StringUtils.capitalize(field.getName()); // 获取get方法的下标 int getIndex = methodAccess.getIndex("get" + fieldName); // 获取set方法的下标 int setIndex = methodAccess.getIndex("set" + fieldName); // 将类名get方法名,方法下标注册到map中 methodIndexMap.put(object.getClass().getName() + "." + "get" + fieldName, getIndex); // 将类名set方法名,方法下标注册到map中 methodIndexMap.put(object.getClass().getName() + "." + "set" + fieldName, setIndex); // 将属性名称放入集合里 fieldList.add(fieldName); } } // 将类名,属性名称注册到map中 fieldMap.put(name, fieldList); methodMap.put(name, methodAccess); return methodAccess; } } /** * @description 复制属性 * @param source * 源数据 * @param targetClass * 目标对象类型 * @return * @author weifei * @date 2020/8/20 10:38 */ public static K copyProperties(T source, Class targetClass) { if (source == null || targetClass == null) { return null; } // 创建对象 try { K k = targetClass.newInstance(); // 复制对象 BeanUtils.copyProperties(source, k); return k; } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } /** * @description 复制属性 * @param source * 源数据 * @param targetClass * 目标对象类型 * @return * @author weifei * @date 2020/12/16 10:12 */ public static List copyProperties(List source, Class targetClass) { if (source == null || targetClass == null) { return null; } List returnValue = new ArrayList<>(); try { source.forEach(s -> { K k = copyProperties(s, targetClass); if (k != null) { returnValue.add(k); } }); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return returnValue; } /** * @description 深度复制对象 * @param source * 元数据 * @param targetClass * 目标对象类型 * @return * @author weifei * @date 2021/3/1 14:21 */ public static K deepCopyObject(T source, Class targetClass) { if (source == null || targetClass == null) { return null; } return JSONObject.parseObject(JSONObject.toJSONBytes(source), targetClass); } /** * @description 深度复制list对象 * @param source * 元数据 * @param targetClass * 目标对象类型 * @return * @author weifei * @date 2021/3/1 14:26 */ public static List deepCopyListObject(List source, Class targetClass) { if (source == null || targetClass == null) { return null; } return JSONObject.parseArray(JSONObject.toJSONString(source), targetClass); } }