|
@@ -1,11 +1,16 @@
|
|
package com.diagbot.util;
|
|
package com.diagbot.util;
|
|
|
|
|
|
|
|
|
|
-import org.springframework.beans.BeanUtils;
|
|
|
|
|
|
+import com.esotericsoftware.reflectasm.ConstructorAccess;
|
|
|
|
+import net.sf.cglib.beans.BeanCopier;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
+
|
|
|
|
+import static java.lang.String.format;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @Description: 对象转换工具类
|
|
* @Description: 对象转换工具类
|
|
@@ -13,6 +18,9 @@ import java.util.List;
|
|
* @time: 2018/12/14 14:21
|
|
* @time: 2018/12/14 14:21
|
|
*/
|
|
*/
|
|
public class BeanUtil {
|
|
public class BeanUtil {
|
|
|
|
+ private static final Map<String, BeanCopier> beanCopierCache = new ConcurrentHashMap<>();
|
|
|
|
+ private static final Map<String, ConstructorAccess> constructorAccessCache = new ConcurrentHashMap<>();
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 把一个对象的属性值复制给另外一个对象的属性值
|
|
* 把一个对象的属性值复制给另外一个对象的属性值
|
|
*
|
|
*
|
|
@@ -20,7 +28,8 @@ public class BeanUtil {
|
|
* @param target 目标对象,即转换后对象
|
|
* @param target 目标对象,即转换后对象
|
|
*/
|
|
*/
|
|
public static void copyProperties(Object source, Object target) {
|
|
public static void copyProperties(Object source, Object target) {
|
|
- BeanUtils.copyProperties(source, target);
|
|
|
|
|
|
+ BeanCopier copier = getBeanCopier(source.getClass(), target.getClass());
|
|
|
|
+ copier.copy(source, target, null);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -32,21 +41,54 @@ public class BeanUtil {
|
|
* @return 转换后列表
|
|
* @return 转换后列表
|
|
*/
|
|
*/
|
|
public static <E> List<E> listCopyTo(List<?> source, Class<E> destinationClass) {
|
|
public static <E> List<E> listCopyTo(List<?> source, Class<E> destinationClass) {
|
|
- try {
|
|
|
|
- if (source.size() == 0) {
|
|
|
|
- return Collections.emptyList();
|
|
|
|
- }
|
|
|
|
- List<E> res = new ArrayList<E>(source.size());
|
|
|
|
- for (Object o : source) {
|
|
|
|
- E e = destinationClass.newInstance();
|
|
|
|
- BeanUtils.copyProperties(o, e);
|
|
|
|
|
|
+ if (ListUtil.isEmpty(source)) {
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ConstructorAccess<E> constructorAccess = getConstructorAccess(destinationClass);
|
|
|
|
+ List<E> res = new ArrayList<>(source.size());
|
|
|
|
+ for (Object o : source) {
|
|
|
|
+ E e = null;
|
|
|
|
+ try {
|
|
|
|
+ e = constructorAccess.newInstance();
|
|
|
|
+ copyProperties(o, e);
|
|
res.add(e);
|
|
res.add(e);
|
|
|
|
+ } catch (Exception ex) {
|
|
|
|
+ throw new RuntimeException(ex);
|
|
}
|
|
}
|
|
- return res;
|
|
|
|
- } catch (IllegalAccessException ex) {
|
|
|
|
- throw new RuntimeException(ex);
|
|
|
|
- } catch (InstantiationException ex) {
|
|
|
|
- throw new RuntimeException(ex);
|
|
|
|
}
|
|
}
|
|
|
|
+ return res;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static BeanCopier getBeanCopier(Class sourceClass, Class targetClass) {
|
|
|
|
+ String beanKey = generateKey(sourceClass, targetClass);
|
|
|
|
+ BeanCopier copier = null;
|
|
|
|
+ if (!beanCopierCache.containsKey(beanKey)) {
|
|
|
|
+ copier = BeanCopier.create(sourceClass, targetClass, false);
|
|
|
|
+ beanCopierCache.put(beanKey, copier);
|
|
|
|
+ } else {
|
|
|
|
+ copier = beanCopierCache.get(beanKey);
|
|
|
|
+ }
|
|
|
|
+ return copier;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static String generateKey(Class<?> class1, Class<?> class2) {
|
|
|
|
+ return class1.toString() + class2.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private static <T> ConstructorAccess<T> getConstructorAccess(Class<T> targetClass) {
|
|
|
|
+ ConstructorAccess<T> constructorAccess = constructorAccessCache.get(targetClass.toString());
|
|
|
|
+ if (constructorAccess != null) {
|
|
|
|
+ return constructorAccess;
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ constructorAccess = ConstructorAccess.get(targetClass);
|
|
|
|
+ constructorAccess.newInstance();
|
|
|
|
+ constructorAccessCache.put(targetClass.toString(), constructorAccess);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new RuntimeException(format("Create new instance of %s failed: %s", targetClass, e.getMessage()));
|
|
|
|
+ }
|
|
|
|
+ return constructorAccess;
|
|
}
|
|
}
|
|
}
|
|
}
|