CGLib实现不同类中同名不同类型属性复制

进行对象复制时,很多框架提供了公共方法,如org.springframework.beans.BeanUtils#copyProperties,org.apache.commons.beanutils.PropertyUtils#copyProperties,org.apache.commons.beanutils.BeanUtils#copyProperties 等,使用过程中发现性能是不如CGLib的的,所以基于BeanCopier造了个轮子,可以提供List的复制和对象的复制。

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.core.Converter;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName: BeanCopierUtil
 * @Description: 属性复制工具
 * @Author: jinfeng17
 * @Date: 2020/12/23 - 14:58
 */
public class BeanCopierUtil {

    private static final ConcurrentHashMap<String, BeanCopier> BEAN_COPIER_CACHE = new ConcurrentHashMap<>();

    /**
     * List转换
     * @param input 要转换的List
     * @param clzz 新List元素类型
     * @param <E>
     * @param <T>
     * @return
     */
    public static <E, T> List<T> convertList2List(List<E> input, Class<T> clzz) {
        List<T> output = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(input)) {
            for (E source : input) {
                T target = BeanUtils.instantiateClass(clzz);
                copyProperties(source, target);
                output.add(target);
            }
        }
        return output;
    }

    /**
     * 同名不同类型属性复制,并使目标对象属性格式化
     *
     * @param source
     * @param target
     */
    public static void copyProperties(Object source, Object target) {
        String key = genKey(source.getClass(), target.getClass());
        BeanCopier beanCopier;
        if (BEAN_COPIER_CACHE.containsKey(key)) {
            beanCopier = BEAN_COPIER_CACHE.get(key);
        } else {
            beanCopier = BeanCopier.create(source.getClass(), target.getClass(), true);
            BEAN_COPIER_CACHE.put(key, beanCopier);
        }
        beanCopier.copy(source, target, new Converter() {
            @Override
            public Object convert(Object value, Class target, Object context) {
                //用到的类型就这三种,没有拓展,如果有其他类型需要,可以自行拓展
                if (value instanceof Integer) {
                    Integer i = (Integer) value;
                    return formatCount(i);
                } else if (value instanceof BigDecimal) {
                    BigDecimal bd = (BigDecimal) value;
                    return formatAmount(bd);
                } else if (value instanceof String) {
                    return value;
                }
                return value;
            }
        });
    }

    private static String genKey(Class<?> srcClazz, Class<?> tgtClazz) {
        return srcClazz.getName() + tgtClazz.getName();
    }

    /**
     * 格式化数量(整数)
     */
    public static String formatCount(Integer integer) {
        if (integer == null) {
            return "0";
        }
        DecimalFormat decimalFormat = new DecimalFormat("###,###");
        return decimalFormat.format(integer);
    }

    /**
     * 格式化金额
     */
    public static String formatAmount(BigDecimal bigDecimal) {
        if (bigDecimal == null || bigDecimal.doubleValue() == 0) {
            return "0.00";
        }
        DecimalFormat decimalFormat = new DecimalFormat("###,###.00");
        return decimalFormat.format(bigDecimal);
    }

    }
原文地址:https://www.cnblogs.com/zjfjava/p/14182786.html