文章目录
前言
在 Java 中,为了更好的实践分层思想,会把会区分 VO-展示层实体,DTO-数据传输层实体,DO-业务层主体,PO-持久层实体等等。尽管他们名字不同,功能也有所不同,但是对于同一个业务主体来说,其相关的实体属性都是大同小异的,这个时候我们可以使用 get/set 方法来操作不过实在是一种下策。本文介绍 BeanUtils 工具类的使用,也是泛型实践的一个例子。
BeanUtils 不光存在于 Spring
本文介绍的 BeanUtils 是取自 Spring-beans 包中的工具方法,但是并非只有 Spring 为我们提供了这种功能的工具类
apache
apache 基金会也为我们提供了具有类似功能的工具类。下面是 apache 提供的工具类的 Maven 依赖,其具体使用本文不会涉及,感兴趣读者可以自己研究一下。
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
cglib
cglib 也为我们提供了类似的功能
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
BeanCopier beanCopier=
BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopier.copy(source, target, null);
Spring 提供的 BeanUtils 用法举例
Maven 依赖
本文 Spring 版本为 4.3.0.RELEASE
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
工具类路径
本文是 泛型使用的举例,所以强烈建议读者看一下源码是怎么实现的
org.springframework.beans.BeanUtils
源实体-一个模拟VO
/**
* 模拟来自前端的实体
* @author jecket
*
*/
public class SourceVO {
private String userName;
private String passWord;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
@Override
public String toString() {
return "SourceVO [userName=" + userName + ", passWord=" + passWord
+ "]";
}
}
目标实体-一个模拟DO
/**
* 模拟后台对应数据库的实体
* @author Jecket
*
*/
public class TargetEntity {
private String userName;
private int age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "TargetEntity [userName=" + userName + ", age=" + age + "]";
}
}
测试调用
测试了两种调用方法,一种是所有同名属性的值都会赋值给目标实体,一种是排除指定属性剩余的同名属性才会赋值给目标实体。
import org.junit.Test;
import org.springframework.beans.BeanUtils;
/**
* 测试 Spring 中 BeanUtils 中
* 具有相同属性名称的实体类间的属性值赋值 方法
*
* 直白的说,就是免去了手动get,set 方法,
* 自动将源实体与目标实体同名属性的值赋值给目标实体的同名属性
* @author WuJieJecket
*
*/
public class SpringBeanUtilsTest {
@Test
public void testCopyProperties(){
//实例化 SourceVO 并赋值
SourceVO source=new SourceVO();
source.setUserName("jecket");
source.setPassWord("******");
//实例化接受数据的实体
TargetEntity target1=new TargetEntity();
TargetEntity target2=new TargetEntity();
//使用 Spring 中 BeanUtils.CopyProperties 方法将同名属性值赋值给另一个实体
//但凡同名的都赋值
BeanUtils.copyProperties(source, target1);
System.out.println("方式一:同名属性全部赋值,source赋值给target1");
System.out.println("source:"+source.toString());
System.out.println("target1:"+target1.toString());
//指定某些属性不赋值,其余但凡同名的都赋值
BeanUtils.copyProperties(source, target2,null,"userName","passWord");
System.out.println("方式二:排除 userName,passWord 属性,其余同名属性全部赋值,source赋值给target2");
System.out.println("source:"+source.toString());
System.out.println("target2:"+target2.toString());
}
测试方法运行结果
方式一:同名属性全部赋值,source赋值给target1
source:SourceVO [userName=jecket, passWord=******]
target1:TargetEntity [userName=jecket, age=0]
方式二:排除 userName,passWord 属性,其余同名属性全部赋值,source赋值给target2
source:SourceVO [userName=jecket, passWord=******]
target2:TargetEntity [userName=null, age=0]
泛型妙用
resource 对象转化到 targetClass 类实例化的一个对象
public <E>E convert2Entity(Object resource, Class targetClass) {
if (resource == null || targetClass==null) {
return null;
}
try {
E target= (E) BeanUtils.instantiateClass(targetClass);
BeanUtils.copyProperties(resource, target);
return (E) target;
} catch (BeansException e) {
log.error("BeansException {}",e);
return null;
}
}
进一步提取
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
public class InfrastructureConvert<SOURCE,TARGET> {
Logger logger = LogManager.getLogger(InfrastructureConvert.class);
public TARGET covert2(SOURCE source, TARGET target) {
if (source == null || target == null) {
return null;
}
try {
BeanUtils.copyProperties(source, target);
return (TARGET) target;
} catch (BeansException e) {
logger.error("BeansException {}", e);
return null;
}
}
}
//测试
@Test
public void testCover1(){
InfrastructureConvert<UserInfoEntity, UserInfo> t = new InfrastructureConvert<UserInfoEntity, UserInfo>();
UserInfoEntity userInfoEntity=UserInfoEntity.builder().id(1L).build();
UserInfo userInfo = new UserInfo();
t.covert2(userInfoEntity,userInfo);
System.out.println(JSON.toJSON(userInfo));
}
//结果
//{"id":1}