gaodm пре 5 година
родитељ
комит
1e4bd42085
2 измењених фајлова са 71 додато и 15 уклоњено
  1. 14 0
      common/pom.xml
  2. 57 15
      common/src/main/java/com/diagbot/util/BeanUtil.java

+ 14 - 0
common/pom.xml

@@ -112,6 +112,20 @@
             <scope>compile</scope>
         </dependency>
 
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib</artifactId>
+            <version>3.3.0</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.esotericsoftware</groupId>
+            <artifactId>reflectasm</artifactId>
+            <version>1.11.9</version>
+            <scope>compile</scope>
+        </dependency>
+
         <!--<dependency>-->
             <!--<groupId>com.fasterxml.jackson.core</groupId>-->
             <!--<artifactId>jackson-core</artifactId>-->

+ 57 - 15
common/src/main/java/com/diagbot/util/BeanUtil.java

@@ -1,11 +1,16 @@
 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.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static java.lang.String.format;
 
 /**
  * @Description: 对象转换工具类
@@ -13,6 +18,9 @@ import java.util.List;
  * @time: 2018/12/14 14:21
  */
 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 目标对象,即转换后对象
      */
     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 转换后列表
      */
     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);
+            } 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;
     }
 }