Java 对象复制(基于Spring BeanUtils)

2019-09-27  本文已影响0人  shaun_x

Spring的BeanUtils的copyProperties只会复制对象的基础属性,所以在此基础上做了迭代处理
支持类,枚举,集合,需要字段名保持一致

import org.springframework.beans.BeanUtils;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.ClassUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class XBeanUtils
{
    public static void copy(Object source, Object target)
    {
        if(source == null)
        {
            target = null;
            return;
        }

        Class<?> actualEditable = target.getClass();

        PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);

        for (PropertyDescriptor targetPd : targetPds)
        {
            Method writeMethod = targetPd.getWriteMethod();
            if (writeMethod != null)
            {
                PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(),
                                                                              targetPd.getName());
                if (sourcePd != null)
                {
                    Method readMethod = sourcePd.getReadMethod();
                    Class writeParamClass = writeMethod.getParameterTypes()[0];
                    if (readMethod != null)
                    {
                        boolean assignable =
                                ClassUtils.isAssignable(writeMethod.getParameterTypes()[0],
                                                        readMethod.getReturnType());
                        boolean isEnum = writeMethod.getParameterTypes()[0].isEnum();
                        boolean isCollection =
                                Collection.class.isAssignableFrom(writeParamClass);
                        if ((assignable || isEnum) && !isCollection)
                        {
                            try
                            {
                                if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()))
                                {
                                    readMethod.setAccessible(true);
                                }
                                Object value = readMethod.invoke(source);
                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()))
                                {
                                    writeMethod.setAccessible(true);
                                }
                                if (isEnum)
                                {
                                    if(value != null)
                                    {
                                        writeMethod.invoke(target,
                                                           Enum.valueOf(writeParamClass,
                                                                        value.toString()));
                                    }
                                }
                                else
                                {
                                    writeMethod.invoke(target, value);
                                }
                            }
                            catch (Throwable ex)
                            {
                                throw new FatalBeanException(
                                        "Could not copy property '" + targetPd.getName() + "'" +
                                                " from source to target",
                                        ex);
                            }
                        }
                        else
                        {
                            // todo add cache
                            try
                            {
                                if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()))
                                {
                                    readMethod.setAccessible(true);
                                }
                                Object sourceValue = readMethod.invoke(source);

                                Object targetValue = null;
                                if (isCollection)
                                {
                                    List targetValues = new ArrayList<>();

                                    ParameterizedType pt =
                                            (ParameterizedType) writeMethod.getGenericParameterTypes()[0];
                                    Class tempClass = (Class) pt.getActualTypeArguments()[0];
                                    if(sourceValue != null)
                                    {
                                        for (Object value : (Collection) sourceValue)
                                        {
                                            Object tempObj = tempClass.newInstance();
                                            copy(value, tempObj);
                                            targetValues.add(tempObj);
                                        }
                                    }
                                    targetValue = targetValues;
                                }
                                else if (sourceValue != null)
                                {
                                    targetValue = writeParamClass.newInstance();
                                    copy(sourceValue, targetValue);
                                }

                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()))
                                {
                                    writeMethod.setAccessible(true);
                                }
                                writeMethod.invoke(target, targetValue);
                            }
                            catch (Exception e)
                            {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读