拷贝实体的工具类---BeanObjectCopyUtils

news2024/9/24 19:15:54

目录

前言:

第一步:引用的核心类:

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

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

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

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

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

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

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

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

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

最后总结:


前言:

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

第一步:引用的核心类:

BeanUtils

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

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

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

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

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

/** @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);
        }
    }
}

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

public static void copyProperties(Object source, Object target) throws BeansException {
    copyProperties(source, target, (Class)null, (String[])null);
}

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

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,然后获取力量吗的所有的属性值,循环进行属性值的赋值操作。

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

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

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;
   }

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

VoucherPostBaseBo vouchPostRecordBO = BeanObjectCopyUtils.copyObject(new VoucherPostBaseBo(), vouchPostRecordVO);

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

List<VoucherPostBaseBo> vouchPostRecordBO = BeanObjectCopyUtils.copyListObjToListObj(VoucherPostBaseBo.class, vouchPostRecordVO);

最后总结:

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/170879.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CMMI之项目管理类

项目管理类过程域涵盖了与项目的计划、监督和控制相关的项目管理活动。CMMI-DEV 中的七个项目管理类过程域是&#xff1a;• 集成项目管理&#xff08;Integrated Project Management&#xff0c; IPM&#xff09;• 项目监督与控制&#xff08;Project Monitoring and Control…

蓝桥杯:城邦

题目链接 问题描述 答案提交 本题答案是&#xff1a;4046。 运行限制 思路分析 代码&#xff08;Java&#xff09; 问题描述 小蓝国是一个水上王国, 有 2021 个城邦, 依次编号 1 到 2021。在任意两 个城邦之间, 都有一座桥直接连接。 为了庆祝小蓝国的传统节日, 小蓝国政府…

登录授权方案:JSON Web Tokens (JWT)

登录授权方案&#xff1a;JSON Web Tokens (JWT) JWT官方文档&#xff1a;https://jwt.io/introduction 1.简介&#xff1a; JWT 即 json web tokens&#xff0c;通过JSON形式作为Web应用中的令牌&#xff0c;用于在各方之间安全地将信息作为JSON对象传输&#xff0c;在数据传…

【博客598】从netfilter hook执行原理分析iptables为什么自定义链无法主动调用只能从其它链跳转过来

从netfilter hook执行原理分析iptables为什么自定义链无法主动调用只能从其它链跳转过来 1、netfilter hook执行原理 netfilter 框架是 Linux 网络子系统里的一个核心模块&#xff0c;iptables 就是基于 netfilter 框架实现的一个网络包处理工具。 netfilter hook被调用后执行…

2023年“科学探索奖”申报启动及指南

2023年“科学探索奖”资助不超过50位青年科学家&#xff0c;每位获奖人5年内将获得总计300万元奖金。今年的申报时间为2023年1月1日至3月15日。获奖名单拟定于2023年8月揭晓。本文知识人网小编整理该奖项的概要及申报指南&#xff0c;以飨读者。“科学探索奖”是一项由科学家主…

【高并发内存池】第二弹之threadcache 线程缓存

1.为什么线程向threadcache申请内存不需要加锁&#xff1f; 因为没有把cache设置成全局变量&#xff0c;而是使用了TLS(线程局部存储)&#xff0c;作用是当前内存只可当前线程见到&#xff0c;其他线程没有使用权&#xff0c;避免了加锁的操作&#xff0c;保证了线程数据的独立…

基于paddlex图像分类模型训练(一):图像分类数据集切分:文件夹转化为imagenet训练格式

背景 在使用paddlex GUI训练图像分类时&#xff0c;内部自动对导入的分类文件夹进行细分&#xff0c;本文主要介绍其图像分类数据切分源码&#xff0c;或可作为其他项目储备代码&#xff1a;https://github.com/PaddlePaddle/PaddleX/blob/develop/paddlex/tools/dataset_spli…

[Linux]进程概念以及进程状态

&#x1f941;作者&#xff1a; 华丞臧. &#x1f4d5;​​​​专栏&#xff1a;【LINUX】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 推荐一款刷题网站 &#x1f449; LeetCode刷题网站 文…

vs2019 + qt5.12.11 打包

目录 你以为打包方式 实际要添加步骤 你以为打包方式 先吐槽一番&#xff0c;感觉vsqt打包有点巨坑&#xff0c;还是说我第一次打包其实都是这样子的 首先我们将生成的.exe弄到一个打包文件夹里面 然后嘞 我用qt自带的打包工具windeployqt exe &#xff08;因为我的再C盘下…

Mysql基础篇(11)—— MySQL8.0新特性之窗口函数

举例1 假设我现在有这样一个数据表&#xff0c;它显示了某购物网站在每个城市每个区的销售额&#xff1a; CREATE TABLE sales( id INT PRIMARY KEY AUTO_INCREMENT, city VARCHAR(15), county VARCHAR(15), sales_value DECIMAL ); INSERT INTO sales(city,county,sales_val…

【xgboost】XGBoost

XGBoost1. 原理改进及特点1.1 遵循Boosting算法的基本建模流程1.2 平衡精确性与复杂度1.3 降低模型复杂度、提升运行效率1.4 保留部份GBDT属性2. sklearn接口(回归)2.1 导库 & 数据2.2 sklearn api普通训练2.3 sklearn api交叉验证2.4 查看属性接口3. xgboost原生代码(回归…

Redis数据持久化方案

作为集中式缓存的优秀代表&#xff0c;Redis可以帮助我们在项目中完成很多特定的功能。Redis准确的说是一个非关系型数据库&#xff0c;但是由于其超高的并发处理性能&#xff0c;及其对于缓存场景所提供的一系列能力构建&#xff0c;使其成为了分布式系统中的集中缓存的绝佳选…

深入学习Vue.js(十)异步组件和函数式组件

文章目录异步组件需要解决的问题异步组件实现原理1.封装defineAsyncComponent函数2.超时与error3.延迟和Loading组件函数式组件异步组件需要解决的问题 允许用户指定加载出错时要渲染的组件允许用户指定Loading组件&#xff0c;以及展示该组件的延迟时间允许用户设置加载组件的…

8. R语言绘图系统介绍、高级绘图与低级绘图、【绘图参数】、绘图函数包

b站课程视频链接&#xff1a; https://www.bilibili.com/video/BV19x411X7C6?p1 腾讯课堂(最新&#xff0c;但是要花钱&#xff0c;我花99&#x1f622;&#x1f622;元买了&#xff0c;感觉讲的没问题&#xff0c;就是知识点结构有点乱&#xff0c;有点废话&#xff09;&…

筑基一层 —— 高质量C编程建议、详解猜数字游戏

目录 一.修炼必备 二.高质量C编程 2.1 高质量C编程的思维导图&#xff08;需要思维导图的加qq:972606225获取) 2.2 文件结构 2.3 程序的形式 2.4 命名规则 三.猜数字游戏详解 一.修炼必备 1.入门必备&#xff1a;VS2019社区版&#xff0c;下载地址&#xff1a;Visual S…

torch_geometric -- Pooling Layers

torch_geometric – Pooling Layers global_add_pool 通过在节点维度上添加节点特征来返回批量图级输出&#xff0c;因此对于单个图 它的输出由下式计算 from torch_geometric.nn import global_mean_pool, global_max_pool, global_add_pool import torch as thf [[1,2,3,4…

Wider Face+YOLOV8人脸检测

YOLO系列的算法更新实在太快了&#xff0c;前些天刚学习完YOLOV7&#xff0c;YOLOV8就出来了。今天先理解模型的训练过程&#xff0c;后续再学习V8的网络结构等细节。YOLOV8源码链接&#xff1a;https://github.com/ultralytics/ultralytics1 数据格式转换Wider Face数据格式转…

java -- 14 多态、内部类、常用API

自动类型转换&#xff1a;多态下引用数据类型的类型转换强制类型转换案例&#xff1a;定义usb接口&#xff1a;定义鼠标和键盘的usb实现类&#xff0c;并有自己特有的方法&#xff0c;重写usb接口的方法&#xff0c;里面穿插了多态创建电脑类&#xff0c;把usb接口揉和进去&…

如何改变视频的MD5值?一分钟让你学会操作

肯定很多不是从事自媒体的朋友对MD5不是很熟悉&#xff0c;但其实它类似于人的身份证&#xff0c;只不过我们的身份证是一串数字&#xff0c;而它则是视频的后台编码&#xff0c;所以这也是一些平台用MD5来判断视频是否重复的依据。那么有人会问了&#xff0c;既然MD5这么特殊&…

Java实战:使用Hutool中的MailUtil实现邮件的发送

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️荣誉&#xff1a; CSDN博客专家、数据库优质创作者&#x1f3c6;&…