SpringBoot2.0 使用cglib beancopier 进行不同层次的对象转换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Nicolas12/article/details/83177011

大家在做wb开发时,肯定会遇到api层参数对象传递给服务层,或者把service层的对象传递给dao层,他们之间又不是同一个类型对象,但字段又是一样,如果还是用普通的get、set方式来处理话,比较繁琐,其中有篇博文讲过使用easymapper来进行对象映射,但在项目中存在不稳性,偶尔出现映射不上的问题,报异常
com.baidu.unbiz.easymapper.exception.MappingException: Generating mapping code failed for ClassMap([A]:Person, [B]:PersonDto), this should not happen, probably the framework could not handle mapping correctly based on your bean
所以使用效率比纯的get和set方法还高的的cglib beancopier,虽然的它的拓展性没有easymapper强,但用来作为对象的copy足够了。
首先导入pom依赖

 <dependency>
            <groupId>asm</groupId>
            <artifactId>asm</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>asm</groupId>
            <artifactId>asm-commons</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>asm</groupId>
            <artifactId>asm-util</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib-nodep</artifactId>
            <version>2.2.2</version>
        </dependency>

工具类

public class CGlibMapper {
     //使用缓存提高效率
    private static final ConcurrentHashMap<String, BeanCopier> mapCaches = new ConcurrentHashMap<>();

    public static <O, T> T mapper(O source, Class<T> target) {
        T instance = baseMapper(source, target);
        return instance;
    }

    public static <O, T> T mapper(O source, Class<T> target, IAction<T> action) {
        T instance = baseMapper(source, target);
        action.run(instance);
        return instance;
    }

    public static <O, T> T mapperObject(O source, T target) {
        String baseKey = generateKey(source.getClass(), target.getClass());
        BeanCopier copier;
        if (!mapCaches.containsKey(baseKey)) {
            copier = BeanCopier.create(source.getClass(), target.getClass(), false);
            mapCaches.put(baseKey, copier);
        } else {
            copier = mapCaches.get(baseKey);
        }
        copier.copy(source, target, null);
        return target;
    }

    public static <O, T> T mapperObject(O source, T target, IAction<T> action) {
        String baseKey = generateKey(source.getClass(), target.getClass());
        BeanCopier copier;
        if (!mapCaches.containsKey(baseKey)) {
            copier = BeanCopier.create(source.getClass(), target.getClass(), false);
            mapCaches.put(baseKey, copier);
        } else {
            copier = mapCaches.get(baseKey);
        }
        copier.copy(source, target, null);
        action.run(target);
        return target;
    }

    private static <O, T> T baseMapper(O source, Class<T> target) {
        String baseKey = generateKey(source.getClass(), target);
        BeanCopier copier;
        if (!mapCaches.containsKey(baseKey)) {
            copier = BeanCopier.create(source.getClass(), target, false);
            mapCaches.put(baseKey, copier);
        } else {
            copier = mapCaches.get(baseKey);
        }
        T instance = null;
        try {
            instance = target.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            log.error("mapper 创建对象异常" + e.getMessage());
        }
        copier.copy(source, instance, null);
        return instance;
    }

    private static String generateKey(Class<?> class1, Class<?> class2) {
        return class1.toString() + class2.toString();
    }

}

其中action的lambda表达式

@FunctionalInterface
public interface IAction<T> {
    void run(T param);
}

下面是各种框架copy的效率
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Nicolas12/article/details/83177011
今日推荐