基于Cglib的高效copy工具类

这里使用的cglib是spring core包的。

import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.core.Converter;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.support.DefaultConversionService;

import java.util.*;

/**
 * <p>使用Cglib高效的复制对象,不使用Spring的BeanCopy,支持类型互相转换。
 * 如果转换失败会抛出{@link ConversionFailedException}异常。
 * 这里的{@link org.springframework.cglib.beans.BeanCopier}
 * 是spring-core包里集成的,不需要单独引入Cglib依赖包。
 * <br/>注意:对象使用了Lombok注解时,不要有{@link Accessors}注解,否则无法复制。
 * </p>
 * <code>
 *
 * </code>
 * @author chengjz
 * @version 1.0
 * @date 2020-04-01 14:46
 */
@Slf4j
public class FastCopy {
	private static final DefaultConversionService conversionService = new DefaultConversionService();
	public static final DefaultConverter converter = new DefaultConverter();

	public static Map<String, BeanCopier> CACHE_MAP = new HashMap<>();

	public static void addBothWayBeanCopy(Class<?> clz1, Class<?> clz2) {
		addBothWayBeanCopy(clz1, clz2, true);
	}

	public static void addBothWayBeanCopy(Class<?> clz1, Class<?> clz2, boolean useConverter) {
		CACHE_MAP.put(buildCacheKey(clz1, clz2), BeanCopier.create(clz1, clz2, useConverter));
		CACHE_MAP.put(buildCacheKey(clz2, clz1), BeanCopier.create(clz2, clz1, useConverter));
	}

	/**
	 * 复制单个对象
	 * @param form 源对象
	 * @param to 复制的对象
	 * @param <T>  复制对象类型
	 * @return 复制对象实例
	 */
	public static <T> T copy(Object form, Class<T> to) {
		return copy(form, to, converter);
	}

	/**
	 * 复制单个对象,自定义类型转换器,除非有必要,否则请使用{@link #copy(Object, Class)}方法
	 * @param form 源对象
	 * @param to 复制的对象
	 * @param converter 类型转换器
	 * @param <T>  复制对象类型
	 * @return 复制对象实例
	 */
	public static <T> T copy(Object form, Class<T> to, Converter converter) {
		T targetSource = null;
		try {
			targetSource = to.newInstance();
		} catch (Exception e) {
			log.error("创建对象发生异常: ", e);
		}
		return copy(form, to, targetSource, converter);
	}


	/**
	 * 复制对象列表
	 * @param formList 源对象列表
	 * @param to 复制的对象
	 * @param <T>  复制对象类型
	 * @return 复制对象实例列表
	 */
	public static <F, T> List<T> listCopy(List<F> formList, Class<T> to) {
		List<T> toList = new ArrayList<>(formList.size());
		formList.forEach(v -> {
			toList.add(copy(v, to));
		});
		return toList;
	}


	public static<T> T copy(Object form, Class<?> to, T targetSource, Converter converter) {
		if (form == null) {
			return targetSource;
		}
		final Class<?> formClass = form.getClass();
		String cacheKey = buildCacheKey(formClass, to);
		if (!CACHE_MAP.containsKey(cacheKey)) {
			addBothWayBeanCopy(formClass, to);
		}
		CACHE_MAP.get(cacheKey).copy(form, targetSource, converter);
		return targetSource;
	}

	private static String buildCacheKey(Class<?> clz1, Class<?> clz2) {
		return clz1.getName() + "_" + clz2.getName();
	}

	public static class DefaultConverter implements Converter {
		@Override
		public Object convert(Object source, Class target, Object context) {
			if (source == null) {
				return null;
			}
			if (isJavaClass(target) || source instanceof Collection<?> || source instanceof Map<?,?>) {
				return conversionService.convert(source, target);
			}
			return copy(source, target);
		}
	}

	public static boolean isJavaClass(Class<?> clz) {
		return clz != null && clz.getClassLoader() == null;
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值