大家在做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的效率