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();
}
}
}
}
}
}
}
}
网友评论