前言

org.springframework.beans.BeanUtils,它提供了对java反射和自省API的包装。它里面还有很多工具类,这里我们介绍一下copyProperties。

我们如果有两个具有很多相同属性的JavaBean对象a和b,想把a中的属性赋值到b,比如接口中将接收到的前端请求参数封装为XxxReqVo,我们想把他转化为XxxQuery对象作为数据库的查询条件,XxxReqVo封装了前端传给我们的参数,接口中我们new了一个XxxQuery对象,属性全是空的,需要把XxxReqVo的相关字段赋值给XxxQuery,最笨的方法就是一个个set

xxQuery.setA(xxReqVO.getA());

如果有几十个需要赋值的的字段呢?那就很头疼了,该工具方法则帮我们大大简化这一步骤

案例

@Data
public class User {private String id;private String name;private String age;private String account;private String password;
}
@Data
public class Person {private String id;private String name;private String age;private String sex;
}
public class Test {public static void main(String[] args) {User user = new User();user.setId("1");user.setAge("2");user.setName("wzh");user.setAccount("wangzh");user.setPassword("1111");Person person = new Person();BeanUtils.copyProperties(user,person);}
}

结果

Person(id=1, name=wzh, age=2, sex=null)

通过上述测试我们就可以总结出相关结论,基本用法为

BeanUtils.copyProperties("转换前的类a", "转换后的类b");

作用:相当于把a的属性赋值给b;

前提:

  • 把a中和b中相同属性名的属性值赋给b;a中和b不相同属性名的属性不会赋值给b
  • a和b类中的属性必须对应setter/getter方法,没有setter/getter则无法完成赋值

官网文档

英文版

Copy the property values of the given source bean into the given target bean.
Note: The source and target classes do not have to match or even be derived from each other, as long as the properties match.
Any bean properties that the source bean exposes but the target bean does not will silently be ignored.As of Spring Framework 5.3, this method honors generic type information when matching properties in the source and target objects.

中文版

将给定源bean的属性值复制到给定的目标bean中。注意:只要属性匹配,源类和目标类不必相互匹配,甚至不必相互派生。源bean公开而目标bean没有公开的任何bean属性都将被静默地忽略。从Spring Framework 5.3开始,当匹配源对象和目标对象中的属性时,该方法将尊重泛型类型信息

源码分析

/**
Params:
source – the source bean #赋值的源对象source
target – the target bean #赋值的目标对象target
editable – the class (or interface) to restrict property setting to  #将属性设置限制为的类(或接口)
ignoreProperties – array of property names to ignore  #要忽略的属性名数组
Throws:
BeansException – if the copying failed*/
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");//获取赋值的目标对象target的class对象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;}/*** 该方法检索给定类(赋值的目标对象target的类型)的JavaBeans propertydescriptor* 返回结果是propertydescriptor数组格式* PropertyDescriptor类:描述了Java Bean通过一对访问器(getter/setter)方法导出的一个属性。* 这里target对象有4个属性,所以targetPds数组长度为4*/PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);for (PropertyDescriptor targetPd : targetPds) {Method writeMethod = targetPd.getWriteMethod();//获取target对象的setter方法(Method类型),例如此时遍历到id这个属性if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {//获取source中和该target属性的写入器(setId)同名的的写入器PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());if (sourcePd != null) { //获取到 => source中有和该target属性的写入器(setId)同名的的写入器Method readMethod = sourcePd.getReadMethod();//获取source的getId方法if (readMethod != null) {  //获取成功ResolvableType sourceResolvableType = ResolvableType.forMethodReturnType(readMethod);ResolvableType targetResolvableType = ResolvableType.forMethodParameter(writeMethod, 0);// Ignore generic types in assignable check if either ResolvableType has unresolvable generics.boolean isAssignable =(sourceResolvableType.hasUnresolvableGenerics() || targetResolvableType.hasUnresolvableGenerics() ?ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType()) :targetResolvableType.isAssignableFrom(sourceResolvableType));if (isAssignable) {try {if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {readMethod.setAccessible(true);}//利用反射读取source源对象中的属性(id)值赋值给value,等价于source.getId();Object value = readMethod.invoke(source);if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {writeMethod.setAccessible(true);}//设置对象target的相关属性值为valuewriteMethod.invoke(target, value);}catch (Throwable ex) {throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", ex);}}}}}}}

核心代码

/**
* 检索给定类的JavaBeans propertydescriptor。参数:clazz -为其检索propertydescriptor的类返回:给定类的propertydescriptor数组抛出:BeansException -如果PropertyDescriptor查找失败
*/
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);

BeanUtils.copyProperties的用法相关推荐

  1. (转载)BeanUtils.copyProperties() 用法

    BeanUtils.copyProperties() 用法 标签: hibernateuserjdbc数据库strutsjava 2009-10-17 23:04 35498人阅读 评论(6) 收藏  ...

  2. BeanUtils.copyProperties与PropertyUtils.copyProperties用法及区别

    转自:http://www.cnblogs.com/fayf/articles/1272982.html 一.简介:BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对J ...

  3. BeanUtils.copyProperties() 用法

    转载自 https://blog.csdn.net/jdjdndhj/article/details/62056137 第一步: BeanUtils.copyProperties()与Property ...

  4. 关于BeanUtils.copyProperties的用法和优缺点

    一.简介:  BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean通常包含了大量的属性,很多情况下,对Jav ...

  5. BeanUtils.copyProperties使用

    BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean通常包含了大量的属性,很多情况下,对JavaBean的处 ...

  6. 使用BeanUtils.copyProperties进行对象之间的属性赋值

    1.使用org.springframework.beans.BeanUtils.copyProperties方法进行对象之间属性的赋值,避免通过get.set方法一个一个属性的赋值 /*** 对象属性 ...

  7. BeanUtils.copyProperties VS PropertyUtils.copyProperties

    1. 通过反射将一个对象的值赋值个另外一个对象(前提是对象中属性的名字相同). 2. BeanUtils.copyProperties(obj1,obj2); 经常闹混不知道是谁给谁赋值,无意中先到& ...

  8. 小知识点BeanUtils.copyProperties

     通过BeanUtils.copyProperties可以时间拷贝对象中的值,下面的new String[]{"cid","agreeFlag"," ...

  9. java对象复制到另一个对象中_spring: beanutils.copyproperties将一个对象的数据塞入到另一个对象中(合并对象)...

    spring: beanutils.copyproperties将一个对象的数据塞入到另一个对象中(合并对象) 它的出现原因: BeanUtils提供对Java反射和自省API的包装.其主要目的是利用 ...

最新文章

  1. iOS开发之用到的几种锁整理
  2. java取字符串中不相同的字母_java 判断两个字符串是否为相同字母异序词 --- 记录...
  3. ThinkPHP 发送post请求
  4. java 安卓视频播放器_java - 学习做一个安卓视频播放器,有一些小问题!忘大家请教...
  5. linux端口转发_详解Linux网桥功能--概念、工作机制、相关命令及实例说明
  6. Spring AMQP + Rabbit 配置多数据源消息队列
  7. sqlserver varchar 对于 sum 运算符无效_在sqlserver上实现自定义函数四舍六入五成双...
  8. 众善之源 or 万恶之源?详析微服务的好与坏
  9. Java的一些基础问题
  10. wxWindows 程序编译选项设置统揽
  11. springboot 运行jar文件报 “XXX中没有主清单属性”
  12. 百度2017春招笔试真题编程题集合 [编程题]买帽子
  13. 【工具使用】GPU的各项参数说明
  14. web 中怎么实现斜线表头效果?
  15. 游戏领域的“抄袭”与“借鉴”之分,无耻与致敬仅有一步之遥
  16. oracle进行排序,oracle排序的几种方法
  17. htc hd2刷android,真正的刷机之王! HTC HD2成功刷入安卓7.0
  18. 海量数据:快速查找一个数字是否出现在40亿个数字中
  19. 2021年数字IC秋招总结
  20. Yolov5 windows下的环境搭建及训练

热门文章

  1. [词性] 二十三、情态动词 2 [ have to ] [ ought to ] [ dare ] [ be able to ] [ needn‘t ] [ had better ]
  2. VMware虚拟机的安装、创建及CentOS 7的安装
  3. 打破网络上不实的健康新闻 朕亨公益教你如何辨识新闻真假
  4. 五边形创意画_我做的数字布球~~看我怎样不用圆规画出正五边形!
  5. 智能车浅谈——电机控制篇
  6. 奥运英语[5] 很高兴再次见到你 Good to see you again.
  7. Sqlserver alter增加列后列名无效
  8. APP推广下载页,如何自动跳转各应用市场
  9. java 多线程 cpu核数_java线程数设置和系统cpu的关系
  10. 碱性干电池的内阻测试方法_实测南孚一号干电池内阻