当前位置: 首页 > web >正文

对象属性复制BeanCopier-笔记

1. BeanCopier简介

org.springframework.cglib.beans.BeanCopier 是 Spring 框架中用于高效复制 Java Bean 属性的工具类。它基于 CGLIB 库实现,相比传统的 BeanUtils.copyProperties() 方法,具有更高的性能,尤其在需要频繁复制对象属性的场景中表现更优。


功能特点

  1. 高性能
    使用字节码生成技术(CGLIB)动态生成复制代码,避免了反射的性能损耗。
  2. 简单属性复制
    仅复制属性名和类型相同的字段,不支持复杂映射(如嵌套对象、自定义转换逻辑)。
  3. 依赖 CGLIB
    需要 CGLIB 库支持,Spring 已内置该依赖(如 spring-core 依赖中已包含 CGLIB)。

与 Spring BeanUtils 的区别

特性BeanCopierBeanUtils.copyProperties()
性能更快(字节码生成)较慢(基于反射)
依赖CGLIBSpring 或 Apache Commons BeanUtils
复杂映射支持不支持不支持
构造函数要求目标类需有无参构造函数同上

2. 使用示例

2.1 常见用法

通常,源、目标对象的属性的名称、类型都一样,无需做额外转换,可直接使用 BeanCopier 做属性复制。

step1. 定义源对象和目标对象

public class User {private String name;private int age;// Getters and Setterspublic String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }
}public class UserDTO {private String name;private int age;// Getters and Setterspublic String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }
}

step2. 使用 BeanCopier 进行属性复制

import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.core.Converter;public class BeanCopierExample {public static void main(String[] args) {// 创建 BeanCopier 实例(第三个参数表示是否使用 Converter,这里User和UserDTO对象的属性字段一致,无需做转换)BeanCopier beanCopier = BeanCopier.create(User.class, UserDTO.class, false);// 源对象和目标对象User user = new User();user.setName("Alice");user.setAge(30);UserDTO userDTO = new UserDTO();// 执行属性复制(第三个参数表示转换所需的Converter,这里无需转换,该参数设置为null即可)beanCopier.copy(user, userDTO, null);System.out.println("Name: " + userDTO.getName()); // 输出: AliceSystem.out.println("Age: " + userDTO.getAge());   // 输出: 30}
}

注意事项

  • 目标类必须有无参构造函数BeanCopier 通过构造函数创建目标对象。
  • 属性名和类型必须一致:若类型不匹配,会抛出异常。
  • 不处理嵌套对象:仅复制简单属性(如 Stringint 等)。

适用场景

  • 高频复制简单 Java Bean 属性(如 DTO 转 VO)。
  • 对性能敏感的场景(如大数据量导出、缓存填充等)。

2.2 需做属性类型转换

当源、目标对象的属性名相同但类型不一致时,可以通过实现 Converter 接口来支持源对象与目标对象之间属性类型的转换。例如将 Date 类型转换为 String 类型,或者将某种业务对象转换为另一种表示形式。

通过传入自定义的 Converter 实现,可以实现:

  • 自定义类型转换逻辑
  • 支持字段级别的转换控制
  • 保持高性能复制的同时处理复杂类型

step1.定义源对象和目标对象,注意 birthDate 字段属性的区别

import java.util.Date;//源类
public class User {private String name;private Date birthDate;public String getName() { return name; }public void setName(String name) { this.name = name; }public Date getBirthDate() { return birthDate; }public void setBirthDate(Date birthDate) { this.birthDate = birthDate; }
}//目标类
public class UserDTO {private String name;private String birthDate; // 注意这里是 String 类型public String getName() { return name; }public void setName(String name) { this.name = name; }public String getBirthDate() { return birthDate; }public void setBirthDate(String birthDate) { this.birthDate = birthDate; }
}

step2.实现 Converter 接口

我们实现一个 Converter 来将 Date 转换为 String(格式化为 yyyy-MM-dd):

import org.springframework.cglib.core.Converter;
import java.text.SimpleDateFormat;
import java.util.Date;public class DateToStringConverter implements Converter {private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");@Overridepublic Object convert(Object source, Class targetClass, Object context) {if (source instanceof Date) {return sdf.format((Date) source);}return source; // 不处理其他类型}
}

convert 方法说明:

  • source:源对象中的属性值
  • targetClass:目标属性的类型
  • context:属性名(String)

step3. 使用 BeanCopier + Converter 完成复制

import org.springframework.cglib.beans.BeanCopier;public class BeanCopierWithConverterExample {public static void main(String[] args) {// 创建 BeanCopier 实例,启用 ConverterBeanCopier beanCopier = BeanCopier.create(User.class, UserDTO.class, true);// 构造源对象User user = new User();user.setName("Alice");user.setBirthDate(new Date());// 构造目标对象UserDTO userDTO = new UserDTO();// 执行复制,传入 Converter 实例beanCopier.copy(user, userDTO, new DateToStringConverter());System.out.println("Name: " + userDTO.getName());System.out.println("Birth Date: " + userDTO.getBirthDate()); // 输出格式如 2025-04-05}
}

使用 Converter 的注意事项

  1. 必须设置 useConverter = true
    在调用 BeanCopier.create() 时,第三个参数必须设为 true,否则 Converter 不会被使用。

  2. Converter 是无状态的
    建议每次复制使用一个新的 Converter 实例,或确保其实现是线程安全的。

  3. 仅转换特定字段
    你可以通过 context 参数(即属性名)判断只对某些字段进行转换。

  4. 不处理嵌套对象
    BeanCopier 不会递归复制嵌套对象,Converter 也仅用于简单属性转换。

Converter的适用场景

  • 源对象和目标对象字段名相同但类型不同(如 Date ↔ String
  • 需要自定义格式化或简化对象结构
  • 性能要求较高,但映射关系简单
http://www.xdnf.cn/news/7760.html

相关文章:

  • 基于正点原子阿波罗F429开发板的LWIP应用(2)——设置静态IP和MAC地址修改
  • Python代码加密与发布方案详解
  • SpringMVC04所有注解按照使用位置划分| 按照使用层级划分(业务层、视图层、控制层)
  • MCP模型上下文协议:基于FastMCP 2.0的实践(2)
  • 机器学习第十九讲:交叉验证 → 用五次模拟考试验证真实水平
  • Linux基础IO(二)
  • upload-labs通关笔记-第14关 文件上传之文件头绕过(图片马)
  • 建筑墙壁红外热成像裂缝潮湿检测数据集VOC+YOLO格式306张2类别
  • 【项目】—高并发内存池
  • AUTOSAR图解==>AUTOSAR_SRS_SAEJ1939
  • day16-17-磁盘管理
  • 流程控制-循环
  • Robot Studio开发入门指南
  • 频分复用信号在信道中的状态
  • 第11天-Python GUI开发实战:Tkinter从入门到项目实践
  • 鸿蒙开发进阶:深入解析ArkTS语言特性与高性能编程实践
  • 【设计模式】基于 Java 语言实现工厂模式
  • 第二届帕鲁杯时间折叠(TimeFold Paradox)
  • 绝缘栅双极型晶体管IGBT的结构与特点
  • 【Git】常用命令大全
  • Git的windows开发与linux开发配置
  • Dify快速上手 MCP,接入高德地图 Server 实战攻略
  • 香港科技大学物理学理学(科学计算与先进材料物理与技术)硕士招生宣讲会——深圳大学
  • 制作一款打飞机游戏52:子弹模式
  • C++显式声明explicit
  • 1G(第一代移动通信系统)详解
  • python 提交 命令到远程windows服务器并获取作业进程id
  • ABAP - SAP与企业微信集成-推送文件到企业微信
  • DeepSeek提示工程Prompt Engineering
  • multipart/* 响应是否必须使用 chunked 编码?