Quellcode durchsuchen

修复无法复制代理对象问题

zhou-hao vor 5 Jahren
Ursprung
Commit
fc5e18d3a2

+ 18 - 4
hsweb-core/src/main/java/org/hswebframework/web/bean/FastBeanCopier.java

@@ -114,9 +114,23 @@ public final class FastBeanCopier {
         return target;
     }
 
+    static Class getUserClass(Object object) {
+        if (object instanceof Map) {
+            return Map.class;
+        }
+        Class type = ClassUtils.getUserClass(object);
+
+        if (java.lang.reflect.Proxy.isProxyClass(type)) {
+            Class[] interfaces= type.getInterfaces();
+            return interfaces[0];
+        }
+
+        return type;
+    }
+
     public static Copier getCopier(Object source, Object target, boolean autoCreate) {
-        Class sourceType = source instanceof Map ? Map.class : ClassUtils.getUserClass(source);
-        Class targetType = target instanceof Map ? Map.class : ClassUtils.getUserClass(target);
+        Class sourceType = getUserClass(source);
+        Class targetType = getUserClass(target);
         CacheKey key = createCacheKey(sourceType, targetType);
         if (autoCreate) {
             return CACHE.computeIfAbsent(key, k -> createCopier(sourceType, targetType));
@@ -541,7 +555,7 @@ public final class FastBeanCopier {
 
             if (targetClass.isEnum()) {
                 if (EnumDict.class.isAssignableFrom(targetClass)) {
-                    String strVal=String.valueOf(source);
+                    String strVal = String.valueOf(source);
 
                     Object val = EnumDict.find((Class) targetClass, e -> {
                         return e.eq(source) || e.name().equalsIgnoreCase(strVal);
@@ -564,7 +578,7 @@ public final class FastBeanCopier {
             if (targetClass.isArray()) {
                 Class<?> componentType = targetClass.getComponentType();
                 List<?> val = convert(source, List.class, new Class[]{componentType});
-                return (T) val.toArray((Object[])Array.newInstance(componentType,val.size()));
+                return (T) val.toArray((Object[]) Array.newInstance(componentType, val.size()));
             }
 
             try {

+ 41 - 3
hsweb-core/src/test/java/org/hswebframework/web/bean/FastBeanCopierTest.java

@@ -1,14 +1,15 @@
 package org.hswebframework.web.bean;
 
-import org.apache.commons.beanutils.BeanUtils;
 import org.junit.Assert;
 import org.junit.Test;
 
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * @author zhouhao
@@ -44,8 +45,8 @@ public class FastBeanCopierTest {
 
     @Test
     public void testMapArray() {
-       Map<String,Object> data =new HashMap<>();
-       data.put("colors", Arrays.asList("RED"));
+        Map<String, Object> data = new HashMap<>();
+        data.put("colors", Arrays.asList("RED"));
 
 
         Target target = new Target();
@@ -82,4 +83,41 @@ public class FastBeanCopierTest {
     }
 
 
+    @Test
+    public void testProxy() {
+        AtomicReference<Object> reference=new AtomicReference<>();
+
+        ProxyTest test = (ProxyTest) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
+                new Class[]{ProxyTest.class}, (proxy, method, args) -> {
+                    if (method.getName().equals("getName")) {
+                        return "test";
+                    }
+
+                    if (method.getName().equals("setName")) {
+                        reference.set(args[0]);
+                        return null;
+                    }
+
+                    return null;
+                });
+
+        Target source = new Target();
+
+        FastBeanCopier.copy(test,source);
+        Assert.assertEquals(source.getName(),test.getName());
+
+
+        source.setName("test2");
+        FastBeanCopier.copy(source,test);
+
+        Assert.assertEquals(reference.get(),source.getName());
+    }
+
+
+    public interface ProxyTest {
+        String getName();
+
+        void setName(String name);
+    }
+
 }