BeanUtils.copyProperties()
是 Spring 框架中的一个工具方法,用于将一个 JavaBean 对象的属性值复制到另一个 JavaBean 对象中。其作用是将源对象的属性值复制到目标对象中,从而实现对象属性的拷贝。下面详细解释其作用和原理:
因此,在使用 BeanUtils.copyProperties()
方法时,需要注意确保源对象和目标对象的属性类型和名称都匹配,以避免类型转换异常或属性复制不完整的情况发生。对于类型不匹配的属性,需要提前进行类型转换或者采取其他适当的处理方式。
BeanUtils.copyProperties()
方法实现的是浅拷贝。
在浅拷贝中,只复制对象的引用,而不复制引用指向的对象。这意味着,如果源对象和目标对象的属性是对象类型(非基本数据类型),则它们在内存中引用的是同一个对象,而不是两个相互独立的对象。因此,如果修改了其中一个对象的属性,另一个对象的相应属性也会受到影响。
举例来说,假设源对象 source
和目标对象 target
都有一个属性 list
,它们都引用同一个 ArrayList 对象。当使用 BeanUtils.copyProperties()
方法进行属性复制时,只会复制 list
属性的引用,而不会复制 ArrayList 对象本身。因此,如果修改了 source
对象的 list
属性,target
对象的 list
属性也会发生变化,因为它们引用的是同一个 ArrayList 对象。
如果需要进行深拷贝,即复制对象及其所有属性的副本,可以考虑使用其他工具或手动实现深拷贝逻辑,例如使用第三方库(如 Apache Commons BeanUtils 中的 BeanUtils.cloneBean()
方法)或手动递归复制对象的所有属性。
1.属性名称和类型匹配问题
源对象和目标对象的属性名称要完全匹配,否则会导致部分属性无法复制或者属性值错误。另外,属性的类型也要保持一致,否则可能会发生类型转换异常。
2.深拷贝问题
BeanUtils.copyProperties()
方法进行的是浅拷贝,如果源对象的属性值是对象类型,并且被多个对象引用,那么目标对象的相应属性值也会引用同一个对象。这可能导致在修改一个对象的属性值时,其他对象的属性值也会受到影响。java
代码解读复制代码//源对象
@Data
public class SourceObject {
private String name;
private int age;
private Map<String,String> map;
}
//目标对象
@Data
public class TargetObject {
private String name;
private int age;
private Map<String,String> map;
}
这时目标对象确实赋值了。但是如果改变map对象,目标对象也会跟着改变。
3.null 值处理
默认情况下,BeanUtils.copyProperties()
方法会将源对象中的所有非 null 属性值复制到目标对象中。如果希望忽略源对象中的 null 属性值,可以使用 BeanUtils.copyProperties()
方法的重载版本,并设置 ignoreNullSource
参数为 true
。
4.bean对应的属性,没有getter和setter方法
BeanUtils.copyProperties
要拷贝属性值成功,需要对应的bean
要有getter和setter
方法。因为它是用反射拿到set和get方法再去拿属性值和设置属性值的。
5.属性是泛型,不会赋值
代码解读复制代码<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.17</version>
</dependency>
注意以下几点:
属性名和数据类型必须匹配:
自动属性映射:
如果源对象和目标对象的属性名不一致,但是数据类型匹配,BeanUtil.copyProperties()
方法会自动进行属性映射,将源对象的属性值复制到目标对象对应的属性中。
1.属性名匹配: 如果源对象和目标对象的属性名完全一致,则直接进行属性值的复制。
2.驼峰命名转换:如果源对象和目标对象的属性名不完全一致,但是符合驼峰命名规范(例如:sourceName 和 targetName),则会尝试进行驼峰命名的转换。例如,将 sourceName
转换为 source_name
,然后与目标对象的属性进行匹配。
3.忽略大小写:属性映射时会忽略属性名的大小写。即使源对象和目标对象的属性名在大小写上有差异,也会尝试进行匹配。
支持嵌套对象的属性复制:
BeanUtil.copyProperties()
方法支持嵌套对象的属性复制,即如果源对象和目标对象的属性包含其他对象类型的属性,也会递归地进行属性复制。支持集合属性的复制:
BeanUtil.copyProperties()
方法支持集合属性的复制,即如果源对象和目标对象的属性包含集合类型(如 List、Set、Map 等)的属性,也会进行正确的复制。处理 null 值:
BeanUtil.copyProperties()
方法不会将该属性复制到目标对象中,目标对象的属性值保持不变。这种行为可以避免将 null 值赋给目标对象的属性。属性是泛型,不会赋值