美文网首页
Java 对象复制(基于Spring BeanUtils)

Java 对象复制(基于Spring BeanUtils)

作者: shaun_x | 来源:发表于2019-09-27 09:25 被阅读0次

    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();
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Java 对象复制(基于Spring BeanUtils)

          本文链接:https://www.haomeiwen.com/subject/ogqwyctx.html