BeanUtils工具类
我们经常需要将不同的两个对象实例进行属性复制,比如将DO对象进行属性复制到DTO,这种转换最原始的方式就是手动编写大量的 get/set代码,很繁琐。为了解决这一痛点,就诞生了一些方便的类库,常用的有 Apache的 BeanUtils,Spring的 BeanUtils, Dozer,Orika等拷贝工具。
1 Spring的BeanUtils方法
BeanUtils.copyProperties
。这个工具类可以帮助我们快速、简便地将一个对象的属性值复制到另一个对象中,非常方便实用。
Spring的BeanUtils方法注意事项
- BeanUtils是浅拷贝。
- 泛型只在编译期起作用,不能依靠泛型来做运行期的限制;
1.1 浅拷贝和深拷贝
- 浅拷贝:对基本数据类型进行值传递,对引用数据类型,使用其引用地址,不拷贝其内容,此为浅拷贝
- 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。
1.2 详解
在 Spring 框架中,BeanUtils.copyProperties 方法的定义如下:
public static void copyProperties(Object source, Object target)
throws BeansException;
该方法接收两个参数,source
和 target
。source
表示要被复制的源对象,target
表示要被赋值的目标对象。我们只需要调用这个方法,就可以将 source
对象的属性值复制到 target
对象中。
除了常规的属性复制,BeanUtils.copyProperties
方法还可以处理嵌套的属性复制。也就是说,如果源对象和目标对象中包含嵌套的 JavaBean
对象,BeanUtils.copyProperties
方法也可以正确地将嵌套对象的属性值复制到目标对象中。
当然,在使用 BeanUtils.copyProperties
方法时,我们需要注意以下几点:
- 源对象和目标对象的属性名称和类型必须匹配。如果源对象和目标对象中的属性名称不匹配,或者属性类型不一致,就会抛出异常。
- 如果源对象中的属性值为 null,那么目标对象中对应的属性也会被设置为 null。如果目标对象中已经存在一个非 null 的属性值,那么这个属性值会被覆盖。
- 对于
JavaBean
对象的复制,BeanUtils.copyProperties
方法会自动创建目标对象的实例。如果目标对象已经存在,那么源对象的属性值将被复制到目标对象中,而不是创建一个新的对象。
2 实例
entity
package com.example.entity;
import lombok.Data;
@Data
public class Question {
private Integer id;
private Integer studentId;
private String content;
private Integer value;
}
package com.example.entity;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
private Integer points;
}
vo
package com.example.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class QuestionStudentVO implements Serializable {
private Integer id;
private String content;
private Integer value;
private Integer studentId;
private List<String> name;
private Integer points;
}
测试类
package com.example;
import com.example.entity.Question;
import com.example.entity.Student;
import com.example.vo.QuestionStudentVO;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
@Test
public void beanUtilTest(){
Question question = new Question();
question.setId(2);
// question.setStudentId(3);
question.setContent("This is content");
question.setValue(100);
Student student = new Student();
student.setId(3);
student.setName("Tony Stark");
student.setPoints(201);
QuestionStudentVO questionStudentVO = new QuestionStudentVO();
BeanUtils.copyProperties(question, questionStudentVO);
BeanUtils.copyProperties(student, questionStudentVO);
System.out.println(questionStudentVO);
}
}
执行结果
QuestionStudentVO(id=3, content=Thi
3 ignoreProperties
将符合条件的属性值全部从一个对象赋值给另一个对象
copyProperties(Object source, Object target)
BeanUtils.copyProperties(model01,model02);
将对象model01
里面的值赋给model02
如果有些对象没有属性,则需要我们手动添加
如果有些对象不想赋值,需要我们手动设置
3.1 忽略某些属性的赋值
copyProperties(Object source, Object target, String… ignoreProperties)
使用BeanUtils.copyProperties(source, target, ignoreProperties)
这个方法,将源的属性,过滤掉一部分属性名,复制到目标上
ignoreProperties的声明类型是String… ignoreProperties
//定义name不赋值
String[] ignoreProperties = {"name"};
BeanUtils.copyProperties(model01,model02,ignoreProperties);