在Java EE项目中有的时候需要在Bo,Vo,Po之间进行复制,如果类中的属性少的话,我们还可以自己通过最简单的set方式赋值,但如果属性多了,比如一个类中有100个属性,难道你需要一步一步的set吗?那岂不是要疯了?所以,我们需要想着用其他的方式解决这个问题,通过不断地研究,写出了下面的解决方案。
使用Spring 的BeanCopier解决不同类之间的深度复制,下面贴出代码,供大家参考:
1.BeanUtils:
2.ClassUtils
使用Spring 的BeanCopier解决不同类之间的深度复制,下面贴出代码,供大家参考:
1.BeanUtils:
package org.example.common.copier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.core.Converter;
public class BeanUtils {
/**
* the beanCopierMap
*/
private static final ConcurrentMap<String, BeanCopier> beanCopierMap = new ConcurrentHashMap<>();
/**
* @description 两个类对象之间转换
* @param source
* @param target
* @return
* @return T
*/
public static <T> T convert(Object source, Class<T> target) {
T ret = null;
if (source != null) {
try {
ret = target.newInstance();
} catch (ReflectiveOperationException e) {
throw new RuntimeException("create class[" + target.getName()
+ "] instance error", e);
}
BeanCopier beanCopier = getBeanCopier(source.getClass(), target);
beanCopier.copy(source, ret, new DeepCopyConverter(target));
}
return ret;
}
public static class DeepCopyConverter implements Converter {
/**
* The Target.
*/
private Class<?> target;
/**
* Instantiates a new Deep copy converter.
*
* @param target
* the target
*/
public DeepCopyConverter(Class<?> target) {
this.target = target;
}
@Override
public Object convert(Object value, Class targetClazz, Object methodName) {
if (value instanceof List) {
List values = (List) value;
List retList = new ArrayList<>(values.size());
for (final Object source : values) {
String tempFieldName = methodName.toString().replace("set",
"");
String fieldName = tempFieldName.substring(0, 1)
.toLowerCase() + tempFieldName.substring(1);
Class clazz = ClassUtils.getElementType(target, fieldName);
retList.add(BeanUtils.convert(source, clazz));
}
return retList;
} else if (value instanceof Map) {
// TODO 暂时用不到,后续有需要再补充
} else if (!ClassUtils.isPrimitive(targetClazz)) {
return BeanUtils.convert(value, targetClazz);
}
return value;
}
}
/**
* @description 获取BeanCopier
* @param source
* @param target
* @return
* @return BeanCopier
*/
public static BeanCopier getBeanCopier(Class<?> source, Class<?> target) {
String beanCopierKey = generateBeanKey(source, target);
if (beanCopierMap.containsKey(beanCopierKey)) {
return beanCopierMap.get(beanCopierKey);
} else {
BeanCopier beanCopier = BeanCopier.create(source, target, true);
beanCopierMap.putIfAbsent(beanCopierKey, beanCopier);
}
return beanCopierMap.get(beanCopierKey);
}
/**
* @description 生成两个类的key
* @param source
* @param target
* @return
* @return String
*/
public static String generateBeanKey(Class<?> source, Class<?> target) {
return source.getName() + "@" + target.getName();
}
}
2.ClassUtils
package org.example.common.copier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Date;
import java.util.Map;
public class ClassUtils {
private static final Map<Class<?>, Class<?>> primitiveMap = new HashMap<>(9);
static {
primitiveMap.put(String.class, String.class);
primitiveMap.put(Boolean.class, boolean.class);
primitiveMap.put(Byte.class, byte.class);
primitiveMap.put(Character.class, char.class);
primitiveMap.put(Double.class, double.class);
primitiveMap.put(Float.class, float.class);
primitiveMap.put(Integer.class, int.class);
primitiveMap.put(Long.class, long.class);
primitiveMap.put(Short.class, short.class);
primitiveMap.put(Date.class, Date.class);
}
/**
* @description 判断基本类型
* @see java.lang.String#TYPE
* @see java.lang.Boolean#TYPE
* @see java.lang.Character#TYPE
* @see java.lang.Byte#TYPE
* @see java.lang.Short#TYPE
* @see java.lang.Integer#TYPE
* @see java.lang.Long#TYPE
* @see java.lang.Float#TYPE
* @see java.lang.Double#TYPE
* @see java.lang.Boolean#TYPE
* @see char#TYPE
* @see byte#TYPE
* @see short#TYPE
* @see int#TYPE
* @see long#TYPE
* @see float#TYPE
* @see double#TYPE
* @param clazz
* @return boolean
*/
public static boolean isPrimitive(Class<?> clazz) {
if (primitiveMap.containsKey(clazz)) {
return true;
}
return clazz.isPrimitive();
}
/**
* @description 获取方法返回值类型
* @param tartget
* @param fieldName
* @return
* @return Class<?>
*/
public static Class<?> getElementType(Class<?> tartget, String fieldName) {
Class<?> elementTypeClass = null;
try {
Type type = tartget.getDeclaredField(fieldName).getGenericType();
ParameterizedType t = (ParameterizedType) type;
String classStr = t.getActualTypeArguments()[0].toString().replace("class ", "");
elementTypeClass = Thread.currentThread().getContextClassLoader().loadClass(classStr);
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
throw new RuntimeException("get fieldName[" + fieldName + "] error", e);
}
return elementTypeClass;
}
}