分享一个对象复制的工具类

  • 使用cglib的BeanCopier复制对象的工具类。
  • 性能比spring的BeanUtils,Apache common的BeanUtils快很多倍。
  • 注意:
  • 1)BeanCopier只拷贝名称和类型都相同的属性
  • 2)当目标类的setter数目比getter少时,创建BeanCopier会失败而导致拷贝不成功
  • 3)引用类型不会拷贝,直接引用,所以操作源对象的引用类型属性会导致copy的对象的引用类型属性一起变化。
public class BeanCopyUtils {
    // 使用WeakHashMap缓存,在内存不足时会自动释放
    private final static Map<String,BeanCopier> BEAN_COPIER_MAP = new WeakHashMap<>();
    private final static Map<String,Converter> CONVERTER_MAP = new WeakHashMap<>();
    private static Object lock1 = new Object();
    private static Object lock2 = new Object();
    private BeanCopyUtils(){}
    /**
     * 创建BeanCopier,并缓存
     * @param src
     * @param target
     * @param useConverter
     * @return
     */
    private static BeanCopier getBeanCopier(Object src,Object target,boolean useConverter) {
        String key = generateKey(src,target,useConverter);
        BeanCopier bc = BEAN_COPIER_MAP.get(key);
        if (null == bc) {
            synchronized (lock1) {
                bc = BEAN_COPIER_MAP.get(key);
                if (null == bc) {
                    bc = BeanCopier.create(src.getClass(),target.getClass(),useConverter);
                    BEAN_COPIER_MAP.put(key,bc);
                    System.out.println("Create BeanCopier with key:" + key);
                }
            }
        }
        return bc;
    }
    /**
     * 复制对象属性
     * @param src
     * @param target
     */
    public static void copy(Object src,Object target) {
        BeanCopier bc = getBeanCopier(src, target, false);
        bc.copy(src,target,null);
    }
    /**
     * 使用自定义的属性转换器复制对象属性
     * @param src
     * @param target
     * @param converter
     */
    public static void copy(Object src,Object target,Converter converter) {
        BeanCopier bc = getBeanCopier(src,target,true);
        bc.copy(src,target,converter);
    }
    /**
     * 对象属性复制,只复制fields中指定的属性,每个属性用逗号分隔
     * @param src
     * @param target
     * @param fields
     */
    public static void copyWithFields(Object src,Object target,final String fields) {
        BeanCopier bc = getBeanCopier(src,target,true);
        bc.copy(src, target, newConverter(src,target,fields,true));
    }
    /**
     * 对象属性复制,排除指定属性
     * @param src
     * @param target
     * @param fields
     */
    public static void copyWithoutFields(Object src,Object target,final String fields) {
        BeanCopier bc = getBeanCopier(src,target,true);
        bc.copy(src, target, newConverter(src,target,fields,false));
    }
    /**
     * new属性转换器,
     * @param fields 需要复制或排除的属性
     * @param fieldCopyFlag 属性复制标识 true:表明fields为需要复制的属性;false:表明fields是需要排除复制的属性
     * @return
     */
    private static Converter newConverter(Object src,Object target,final String fields,final boolean fieldCopyFlag) {
        String key = buildConverterkey(src,target,fields,fieldCopyFlag);
        Converter converter = CONVERTER_MAP.get(key);
        if (null == converter) {
            synchronized (lock2) {
                converter = CONVERTER_MAP.get(key);
                if (null == converter) {
                    converter = new Converter() {
                        @Override
                        public Object convert(Object fieldValue, Class fieldType, Object methodName) {
                            String field = methodName.toString().substring(3); // 得到属性名,如Name
                            field = field.substring(0,1).toLowerCase() + field.substring(1); // 将首字母小写
                            if ((fieldCopyFlag && fields.contains(field)) || (!fieldCopyFlag && !fields.contains(field))) {
                                return fieldValue;
                            }
                            return null;
                        }
                    };
                    CONVERTER_MAP.put(key,converter);
                    System.out.println("Created Converter with key:" + key);
                }
            }
        }
        return converter;
    }
    private static String generateKey(Object src,Object target,boolean useConverter) {
        return src.getClass().getName() + target.getClass().getName() + String.valueOf(useConverter);
    }
    private static String buildConverterkey(Object src,Object target,String fields,boolean copyFlag) {
        String baseKey = generateKey(src,target,true);
        String key = baseKey + fields + String.valueOf(copyFlag);
        return key;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值