package com.vci.starter.web.util; import com.vci.starter.web.toolmodel.DateConverter; import org.springframework.cglib.beans.BeanCopier; import org.springframework.cglib.core.Converter; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** * 对象拷贝工具类 * 使用的cglib的beancopier,因为使用了转换器,所以性能比没有使用转换器的要低一些 * 会自动判断是否需要转换器,当有属性相同,类型不同,和有对象类型,map,list等集合类型时才需要转换器 * @author weidy * @date 2019/11/23 9:22 AM */ public class BeanUtil { /** * 存放拷贝对象的缓存 */ private static final ConcurrentMap beanCopierMap = new ConcurrentHashMap<>(); /** * 获取类拷贝的对象 * @param source 源对象类 * @param target 目标对象类 * @param useConverter 是否使用转换器 * @return 拷贝对象 */ public static BeanCopier getBeanCopier(Class source, Class target,boolean useConverter) { String beanCopierKey = generateBeanKey(source, target); if (beanCopierMap.containsKey(beanCopierKey)) { return beanCopierMap.get(beanCopierKey); } else { BeanCopier beanCopier = BeanCopier.create(source, target, useConverter); beanCopierMap.putIfAbsent(beanCopierKey, beanCopier); } return beanCopierMap.get(beanCopierKey); } /** * 生成两个类的key,用于存放到缓存之中 * @param source 源对象类型 * @param target 目标对象类 * @return 两个类的名称连接到一起后的名字 */ public static String generateBeanKey(Class source, Class target) { return source.getName() + "@" + target.getName(); } /** * 两个对象之间转换 * @param source 源对象 * @param target 目标对象 * @param useConvert 是否使用默认的转换器,请在出现属性名称相同而类型不同,或者有对象类型,集合属性时才转换 */ public static void convert(Object source,Object target,boolean useConvert){ if(source != null && target !=null){ BeanCopier beanCopier = getBeanCopier(source.getClass(),target.getClass(),useConvert); beanCopier.copy(source,target,useConvert?new DeepCopyConverter(target):null); } } /** * 两个对象之间转换 * @param source 源对象 * @param target 目标对象 * @return 目标对象 */ public static void convert(Object source,Object target){ convert(source,target,true); } /** * 深度拷贝转换器 */ public static class DeepCopyConverter implements Converter { /** * 目标对象 */ private Object target; /** * 构造方法 * @param target 目标对象 */ public DeepCopyConverter(Object target) { this.target = target; } /** * 执行拷贝 * @param value 源对象的属性的值 * @param targetClazz 目标对象的属性的类 * @param methodName set方法的名字 * @return 转换后的值 */ @Override public Object convert(Object value, Class targetClazz, Object methodName) { if (value instanceof List) { List values = (List) value; List retList = new ArrayList<>(values.size()); copyForCollection(values,retList,methodName); return retList; } else if(value instanceof Set){ Set values = (Set) value; Set retSet = new HashSet<>(); copyForCollection(values,retSet,methodName); } else if(value instanceof Vector){ Vector values = (Vector)value; Vector retVector = new Vector(); copyForCollection(values,retVector,methodName); }else if (value instanceof Map) { Map values = (Map)value; Map retMap = new HashMap(); for (final Object key : values.keySet()) { Object mapValue = values.get(key); String tempFieldName = methodName.toString().replace("set", ""); String fieldName = tempFieldName.substring(0, 1) .toLowerCase() + tempFieldName.substring(1); Class clazz = ClassUtil.getElementType(target.getClass(), fieldName); Object targetAttr = null; try{ targetAttr = clazz.newInstance(); }catch (Throwable e){ //新的对象的属性初始化出错 } BeanUtil.convert(mapValue, targetAttr); retMap.put(key,targetAttr); } } else if (!ClassUtil.isPrimitive(targetClazz)) { //这个是对象类型 Object targetAttr = null; try{ targetAttr = targetClazz.newInstance(); }catch (Throwable e){ //新的对象属性初始化出错 } BeanUtil.convert(value, targetAttr); return targetAttr; } if(value instanceof Boolean && targetClazz.equals(String.class)){ //从boolean拷贝到string return String.valueOf(value); } if(value instanceof String && (targetClazz.equals(Boolean.class) || targetClazz.equals(boolean.class))){ //从String拷贝到boolean if("true".equalsIgnoreCase((String)value)){ return true; }else{ return false; } } if(value instanceof Date && targetClazz.equals(String.class)){ //时间格式 return VciDateUtil.date2Str((Date)value,VciDateUtil.DateTimeMillFormat); } if(value instanceof String && targetClazz.equals(Date.class)){ //转换 DateConverter dateConverter = new DateConverter(); dateConverter.setAsText((String)value); return dateConverter.getValue(); } return value; } /** * 处理集合属性 * @param sourceCollection 源对象中集合属性的的值 * @param targetCollection 目标对象的集合属性的值 * @param methodName setter方法 */ private void copyForCollection(Collection sourceCollection,Collection targetCollection,Object methodName){ for (final Object source : sourceCollection) { if(source instanceof Collection){ List targetValues = new ArrayList<>(); copyForCollection((Collection)source,targetValues,methodName); targetCollection.add(targetValues); }else if(source instanceof Map){ String tempFieldName = methodName.toString().replace("set", ""); String fieldName = tempFieldName.substring(0, 1) .toLowerCase() + tempFieldName.substring(1); Class clazz = ClassUtil.getElementType(target.getClass(), fieldName); Object targetAttr = null; try { targetAttr = clazz.newInstance(); } catch (Throwable e) { //新的对象的属性初始化出错 } Map map = (Map) source; for(Object key : map.keySet()){ VciBaseUtil.setValueForField(key.toString(),targetAttr,VciBaseUtil.getStringValueFromObject(map.get(key))); } targetCollection.add(targetAttr); }else { String tempFieldName = methodName.toString().replace("set", ""); String fieldName = tempFieldName.substring(0, 1) .toLowerCase() + tempFieldName.substring(1); Class clazz = ClassUtil.getElementType(target.getClass(), fieldName); Object targetAttr = null; try { targetAttr = clazz.newInstance(); } catch (Throwable e) { //新的对象的属性初始化出错 } BeanUtil.convert(source, targetAttr); targetCollection.add(targetAttr); } } } } }