前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring\spring boot拷贝实体的工具类---BeanObjectCopyUtils

spring\spring boot拷贝实体的工具类---BeanObjectCopyUtils

原创
作者头像
小马哥学JAVA
发布2023-01-19 09:38:57
5750
发布2023-01-19 09:38:57
举报
文章被收录于专栏:JAVA开发专栏JAVA开发专栏

目录

前言:

第一步:引用的核心类:

第一种:单个实体的拷贝方法

第二种:列表类的实体拷贝方法

第二步:核心方法的介绍:

核心方法一,介绍了实例化的操作:

核心方法二、拷贝属性的方法:

核心方法三、具体的实现的方法:

第三步:项目中创建工具类的核心代码

使用方法一、单个实体类的拷贝操作;

使用方法二、多个实体类(实体类列表的拷贝操作)

最后总结:


前言:

介绍一个实用的bean对象实体类的拷贝工具,主要封装了两个方法进行实体类的字符拷贝处理,单个实体以及实体列表的拷贝操作。

第一步:引用的核心类:

BeanUtils

核心的思想是根据反射进行类中成员变量的赋值操作,本文一共实现了两种方式的实体拷贝方法:

第一种:单个实体的拷贝方法

第二种:列表类的实体拷贝方法

第二步:核心方法的介绍:

核心方法一,介绍了实例化的操作:

代码语言:javascript
复制
/** @deprecated */
@Deprecated
public static <T> T instantiate(Class<T> clazz) throws BeanInstantiationException {
    Assert.notNull(clazz, "Class must not be null");
    if (clazz.isInterface()) {
        throw new BeanInstantiationException(clazz, "Specified class is an interface");
    } else {
        try {
            return clazz.newInstance();
        } catch (InstantiationException var2) {
            throw new BeanInstantiationException(clazz, "Is it an abstract class?", var2);
        } catch (IllegalAccessException var3) {
            throw new BeanInstantiationException(clazz, "Is the constructor accessible?", var3);
        }
    }
}

核心方法二、拷贝属性的方法:

代码语言:javascript
复制
public static void copyProperties(Object source, Object target) throws BeansException {
    copyProperties(source, target, (Class)null, (String[])null);
}

核心方法三、具体的实现的方法:

代码语言:javascript
复制
private static void copyProperties(Object source, Object target, @Nullable Class<?> editable, @Nullable String... ignoreProperties) throws BeansException {
    Assert.notNull(source, "Source must not be null");
    Assert.notNull(target, "Target must not be null");
    Class<?> actualEditable = target.getClass();
    if (editable != null) {
        if (!editable.isInstance(target)) {
            throw new IllegalArgumentException("Target class [" + target.getClass().getName() + "] not assignable to Editable class [" + editable.getName() + "]");
        }

        actualEditable = editable;
    }

    PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
    List<String> ignoreList = ignoreProperties != null ? Arrays.asList(ignoreProperties) : null;
    PropertyDescriptor[] var7 = targetPds;
    int var8 = targetPds.length;

    for(int var9 = 0; var9 < var8; ++var9) {
        PropertyDescriptor targetPd = var7[var9];
        Method writeMethod = targetPd.getWriteMethod();
        if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
            PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
            if (sourcePd != null) {
                Method readMethod = sourcePd.getReadMethod();
                if (readMethod != null && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
                    try {
                        if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                            readMethod.setAccessible(true);
                        }

                        Object value = readMethod.invoke(source);
                        if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                            writeMethod.setAccessible(true);
                        }

                        writeMethod.invoke(target, value);
                    } catch (Throwable var15) {
                        throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", var15);
                    }
                }
            }
        }
    }

}

这个也是spring-bean的官方方式,使用起来也比较放心,源码的逻辑看着是先反射成class,然后获取力量吗的所有的属性值,循环进行属性值的赋值操作。

第三步:项目中创建工具类的核心代码

实际的应用代码中只需要下面的方法即可,上面是讲解了一些源码的逻辑。

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;


/**
 * 对象拷贝工具
 * @author DELL
 * @version 1.0
 */
public class BeanObjectCopyUtils{

   private static  Logger LOGGER = LoggerFactory.getLogger( BeanObjectCopyUtils.class );


   /**
    * 拷贝对象
    * @param desObj 目标对象
    * @param origObj 源对象
    * @return  desObj 目标对象
    */
   public static <T,E> T copyObject(T desObj, E origObj){
      if(origObj!=null && desObj!=null){
         try {
            BeanUtils.copyProperties(origObj, desObj);
         }
         catch (Exception e) {
            LOGGER.error("object copy error",e);
            throw new RuntimeException("object copy error",e);
         }
      }
      return desObj;
   }


   /**
    * 拷贝List对象到另一个list对象
    * @param desClass  源List对象
    * @param sourceList 目标List对象
    * @return  List
    */
   @SuppressWarnings({ "rawtypes", "unchecked" })
   public static <T> List<T> copyListObjToListObj(Class<T> desClass, List sourceList){
      List desList=new ArrayList();
      if(sourceList!=null){
         for(int i=0; i<sourceList.size(); i++){
            try {
               Object  sourceObj = sourceList.get(i);
               Object  desObj = desClass.newInstance();
               BeanUtils.copyProperties(sourceObj, desObj);
               desList.add(desObj);
            }
            catch (Exception e) {
               LOGGER.error("list copy error",e);
               throw new RuntimeException("list copy error",e);
            }

         }
      }
      return desList;
   }

使用方法一、单个实体类的拷贝操作;

代码语言:javascript
复制
VoucherPostBaseBo vouchPostRecordBO = BeanObjectCopyUtils.copyObject(new VoucherPostBaseBo(), vouchPostRecordVO);

使用方法二、多个实体类(实体类列表的拷贝操作)

代码语言:javascript
复制
List<VoucherPostBaseBo> vouchPostRecordBO = BeanObjectCopyUtils.copyListObjToListObj(VoucherPostBaseBo.class, vouchPostRecordVO);

最后总结:

在封装一些工具类的时候,最好是使用一些官方定义的方法进行二次封装处理,这样有以下的好处,第一,可以保证封装方法的稳定性、安全性;第二,封装的方法之后,可以进行一些根据项目的实际情况进行特殊的处理,比如说日志的处理,报警的处理等等

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言:
  • 第一步:引用的核心类:
    • 第一种:单个实体的拷贝方法
      • 第二种:列表类的实体拷贝方法
      • 第二步:核心方法的介绍:
        • 核心方法一,介绍了实例化的操作:
          • 核心方法二、拷贝属性的方法:
            • 核心方法三、具体的实现的方法:
            • 第三步:项目中创建工具类的核心代码
              • 使用方法一、单个实体类的拷贝操作;
                • 使用方法二、多个实体类(实体类列表的拷贝操作)
                • 最后总结:
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档