java 复制对象 cglib_Java对象的拷贝和转换,BeanUtils拷贝和 cglib拷贝

import java.beans.PropertyDescriptor;

import java.io.IOException;

import java.lang.reflect.Field;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.ArrayList;

import java.util.Collections;

import java.util.HashMap;

import java.util.HashSet;

import java.util.List;

import java.util.Map;

import java.util.Objects;

import java.util.Set;

import java.util.concurrent.ConcurrentHashMap;

import java.util.function.BiConsumer;

import java.util.function.BiPredicate;

import java.util.function.Consumer;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.BeanUtils;

import org.springframework.beans.BeanWrapper;

import org.springframework.beans.BeanWrapperImpl;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONException;

import com.alibaba.fastjson.JSONObject;

import com.alibaba.fastjson.parser.Feature;

import com.alibaba.fastjson.serializer.SerializerFeature;

import net.sf.cglib.beans.BeanCopier;

import net.sf.cglib.beans.BeanMap;

/**

Title: TemplateCodeUtil

*

Description: 对象拷贝与转化

* @author houzw

* @date 2019年4月18日

*/

public class TemplateCodeUtil {

protected static final Logger logger = LoggerFactory.getLogger(TemplateCodeUtil.class);

// 使用多线程安全的Map来缓存BeanCopier,由于读操作远大于写,所以性能影响可以忽略

public static ConcurrentHashMap beanCopierMap = new ConcurrentHashMap();

/**

* 通过cglib BeanCopier形式,使用cglib拷贝,同属性同类型拷贝

*

* @param source 源转换的对象

* @param target 目标转换的对象

*/

public static void copyProperties(Object source, Object target) {

String beanKey = generateKey(source.getClass(), target.getClass());

BeanCopier copier = null;

if (beanCopierMap.containsKey(beanKey)) {

copier = beanCopierMap.get(beanKey);

} else {

copier = BeanCopier.create(source.getClass(), target.getClass(), false);

beanCopierMap.putIfAbsent(beanKey, copier);// putIfAbsent已经实现原子操作了。

}

copier.copy(source, target, null);

}

/**

* 通过cglib BeanCopier形式,使用cglib拷贝,同属性同类型拷贝

*

* @param source 源转换的对象

* @param target 目标转换的对象

* @param action 支持Lambda函数给拷贝完的对象一些自定义操作

* @return

*/

public static T copyProperties(O source, T target, Consumer action) {

String beanKey = generateKey(source.getClass(), target.getClass());

BeanCopier copier = null;

if (beanCopierMap.containsKey(beanKey)) {

copier = beanCopierMap.get(beanKey);

} else {

copier = BeanCopier.create(source.getClass(), target.getClass(), false);

beanCopierMap.putIfAbsent(beanKey, copier);// putIfAbsent已经实现原子操作了。

}

copier.copy(source, target, null);

action.accept(target);

return target;

}

private static String generateKey(Class> class1, Class> class2) {

return class1.toString() + class2.toString();

}

/**

* transalte常规反射拷贝,同名同类型拷贝,推荐使用 transTo(O o, Class clazz)

* ×通过常规反射形式 DTO对象转换为实体对象。如命名不规范或其他原因导致失败。

* @param t 源转换的对象

* @param e 目标转换的对象

*

*/

public static void transalte(T t, O e) {

Method[] tms = t.getClass().getDeclaredMethods();

Method[] tes = e.getClass().getDeclaredMethods();

for (Method m1 : tms) {

if (m1.getName().startsWith("get")) {

String mNameSubfix = m1.getName().substring(3);

String forName = "set" + mNameSubfix;

for (Method m2 : tes) {

if (m2.getName().equals(forName)) {

// 如果类型一致,或者m2的参数类型是m1的返回类型的父类或接口

boolean canContinue = m2.getParameterTypes()[0].isAssignableFrom(m1.getReturnType());

if (canContinue) {

try {

m2.invoke(e, m1.invoke(t));

break;

} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {

// log未配置会报 WARN No appenders could be found for

// logger log4j:WARN Please initialize the log4j

// system properly.

logger.debug("DTO 2 Entity转换失败");

e1.printStackTrace();

}

}

}

}

}

}

// logger.debug("转换完成");

}

/**

* 对象属性拷贝,忽略源转换对象的 null值

* @param t 源转换的对象

* @param e 目标转换的对象

*

*/

public static void copyPropertiesIgnoreNull(T t, O e) {

final BeanWrapper bw = new BeanWrapperImpl(t);

PropertyDescriptor[] pds = bw.getPropertyDescriptors();

Set emptyNames = new HashSet();

for(PropertyDescriptor pd : pds) {

Object srcValue = bw.getPropertyValue(pd.getName());

if (srcValue != null) emptyNames.add(pd.getName());

}

partialCopy(t, e, emptyNames.toArray());

}

/**

* 对象属性拷贝,同属性同类型拷贝,忽略源转换对象不符合自定义规则的属性

* @param t 源转换的对象

* @param e 目标转换的对象

* @param action lambda传入的是t的属性名和属性值,返回true和e对象有该属性则拷贝该值

*/

public static void copyPropertiesIgnoreCustom(T t, O e, BiPredicate action) {

final BeanWrapper bw = new BeanWrapperImpl(t);

PropertyDescriptor[] pds = bw.getPropertyDescriptors();

Set emptyNames = new HashSet();

for(PropertyDescriptor pd : pds) {

Object srcValue = bw.getPropertyValue(pd.getName());

// 自定义条件的成立与否,返回true则拷贝,反之不拷贝,满足同属性同类型。

if (action.test(pd.getName(), srcValue)) emptyNames.add(pd.getName());

}

partialCopy(t, e, emptyNames.toArray());

}

/** 同类型字段部分拷贝

* @param t 源数据对象

* @param e 接收对象

* @param key 要拷贝的字段名数组

*/

public static void partialCopy(T t , T e, Object... key) {

BeanMap t1 = BeanMap.create(t);

BeanMap e1 = BeanMap.create(e);

int i = key.length;

while (i-- > 0) {

e1.replace(key[i], t1.get(key[i]));

}

}

/**

* 对象集合转换,两个对象的属性名字需要一样

*/

public static List transTo(List fromList, Class clazz) throws IllegalAccessException, InstantiationException, InvocationTargetException {

List toList = new ArrayList<>();

for (O e : fromList) {

T entity = clazz.newInstance();

BeanUtils.copyProperties(e, entity);

toList.add(entity);

}

return toList;

}

/**

* 对象集合转换,两个对象的属性名字需要一样,并可自定义设置一些参数

*/

public static List transTo(List fromList, Class clazz, OnTransListener onTransListener) throws IllegalAccessException, InstantiationException, InvocationTargetException {

List toList = new ArrayList<>();

for (O e : fromList) {

T entity = clazz.newInstance();

BeanUtils.copyProperties(e, entity);

if (onTransListener != null) {

onTransListener.doSomeThing(entity, e);

}

toList.add(entity);

}

return toList;

}

/**

* 使用BeanUtils,对象集合转换,两个对象的属性名字需要一样,并可自定义设置一些参数

*

* @param fromList 源数据List

* @param clazz 需要转换成的clazz

* @param action 支持lambda表达式自定义设置一些参数

* @return

*/

public static List transToCustom(List fromList, Class clazz, BiConsumer action) throws IllegalAccessException, InstantiationException, InvocationTargetException {

List toList = new ArrayList<>();

for (O e : fromList) {

T entity = clazz.newInstance();

BeanUtils.copyProperties(e, entity);

action.accept(e, entity);

toList.add(entity);

}

return toList;

}

/**

* 使用BeanUtils,对象转换,E转为t对象

*/

public static T transTo(O e, Class clazz) throws IllegalAccessException, InstantiationException, InvocationTargetException {

T t = clazz.newInstance();

BeanUtils.copyProperties(e, t);

return t;

}

/**

* 接口常量转为指定类型的List

*/

public static List interfaceTransToVal(Class> clazz, Class toClazz) throws IllegalAccessException {

List list = new ArrayList<>();

Field[] fields = clazz.getDeclaredFields();

for (Field field : fields) {

T t = (T) field.get(clazz);

if (t.getClass() == toClazz) {

list.add(t);

}

}

return list;

}

/**

* json 转为对象

*/

public static T jsonToObject(String jsonStr, Class clazz) {

// ObjectMapper objectMapper = new ObjectMapper();

T t = null;

try {

t = JSONObject.parseObject(jsonStr, clazz);

// t = objectMapper.readValue(jsonByte, clazz);

} catch (JSONException e) {

e.printStackTrace();

}

return t;

}

/**

* json 转为Array

*/

public static List jsonToArray(String jsonStr, Class clazz) {

if (jsonStr == null || jsonStr.length() == 0) {

return null;

} else {

// ObjectMapper objectMapper = new ObjectMapper();

List arr = null;

try {

arr = JSON.parseArray(jsonStr, clazz);

// JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, clazz);

// arr = objectMapper.readValue(jsonStr, javaType);

} catch (JSONException e) {

e.printStackTrace();

}

return arr;

}

}

/**

* Map 转为对象,字段格式要一致

*/

public static T mapTrasnToObject(Map map, Class clazz) throws IOException {

byte[] jsonBytes = JSON.toJSONBytes(map, SerializerFeature.WriteNullStringAsEmpty);

T t = JSON.parseObject(jsonBytes, clazz,Feature.IgnoreNotMatch);

// ObjectMapper objectMapper = new ObjectMapper();

// String jsonStr = objectMapper.writeValueAsString(map);

// T t = objectMapper.readValue(jsonStr, clazz);

return t;

}

/**

* object(非基本类型和List类型)转为 Map

* 若类型不正确返回的map为EmptyMap,其不可添加元素

* @param obj

* @return

*/

@SuppressWarnings("unchecked")

public static Map objectTrasnToMap(Object obj) {

if (Objects.isNull(obj)) {

return Collections.EMPTY_MAP;

} else {

Map map = BeanMap.create(obj);

return map.size() == 1 && map.containsKey("empty") ? Collections.EMPTY_MAP : new HashMap<>(map);

}

}

/**

* 集合根据某个关键字进行分组

*/

public static Map> groupBy(List tList, StringKey stringKey) {

Map> map = new HashMap<>();

for (T t : tList) {

if (map.containsKey(stringKey.key(t))) {

map.get(stringKey.key(t)).add(t);

} else {

List list = new ArrayList<>();

list.add(t);

map.put(stringKey.key(t), list);

}

}

return map;

}

/**

* 把对象转为json,并输出到日志中

*/

public static void logObject(String tag, Object object) {

try { // 保留空值数据为 ""

String json = JSON.toJSONString(object, SerializerFeature.WriteNullStringAsEmpty);

// ObjectMapper objectMapper = new ObjectMapper();

// String json = objectMapper.writeValueAsString(object);

logger.info("{}{}", tag, json);

} catch (JSONException e) {

e.printStackTrace();

logger.info("exception = {}", e);

}

}

/**

* 集合分组的关键词

*/

public interface StringKey {

String key(T t);

}

/**

* 编写一些额外逻辑

*/

public interface OnTransListener {

void doSomeThing(T t, O e);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值