cn.acyou.leo.framework.util.BeanCopyUtil Maven / Gradle / Ivy
package cn.acyou.leo.framework.util;
import cn.acyou.leo.framework.exception.ServiceException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Bean 之间的拷贝
*
* @author youfang
*/
@Slf4j
public class BeanCopyUtil {
/**
* 复制
*
* @param 目标对象
* @param 源对象
* @param t 源对象
* @param clz 目标对象Class
* @return 目标对象
*/
public static E copy(T t, Class clz) {
if (t == null) {
return null;
}
try {
E instance = clz.newInstance();
BeanUtils.copyProperties(t, instance);
return instance;
} catch (Exception e) {
log.error(e.getMessage(), e);
}
//return null;会导致编译器空指针检查警告,理论上不会出现此情况,所以抛出异常。
throw new ServiceException("BeanCopy出错了!{}->{}", t, clz.getName());
}
/**
* 复制对象List
*
* @param 目标对象
* @param 源对象
* @param l 源对象集合
* @param clz 目标对象Class
* @return 目标对象集合
*/
public static List copyList(Collection l, Class clz) {
List list = new ArrayList<>();
if (!CollectionUtils.isEmpty(l)) {
l.forEach(item -> list.add(copy(item, clz)));
}
return list;
}
/**
* 以JSON的方式复制对象
*
* @param 目标对象
* @param o 源对象
* @param clz 目标对象Class
* @return 目标对象集合
*/
public static E copyByJson(Object o, Class clz) {
String json = JSON.toJSONString(o);
return JSON.parseObject(json, clz);
}
/**
* 以JSON的方式复制对象(对于泛型对象)
*
* @param 目标对象
* @param o 源对象
* @param typeReference 目标对象Class
* @return 目标对象集合
*/
public static E copyByJson(Object o, TypeReference typeReference) {
String json = JSON.toJSONString(o);
return JSON.parseObject(json, typeReference);
}
/**
* 合并属性 (不会使用null覆盖目标)
*
* @param 对象类型
* @param target 目标
* @param destination 目的
*/
public static void merge(M target, M destination) {
merge(target, destination, false);
}
/**
* 合并属性
*
* @param 对象类型
* @param target 目标
* @param destination 目的地
* @param nullCoverTarget 使用null覆盖目标
*/
public static void merge(M target, M destination, boolean nullCoverTarget) {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(target.getClass());
for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) {
if (descriptor.getWriteMethod() != null) {
Object defaultValue = descriptor.getReadMethod().invoke(destination);
if (defaultValue == null && !nullCoverTarget) {
continue;
}
descriptor.getWriteMethod().invoke(target, defaultValue);
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}