乐趣区

mica cglib 增强——[1]cglib bean copy 介绍

专栏介绍
本套专栏主要是介绍微服务核心框架 Mica 中对 Cglib bean copy 的一系列增强,保证高性能的同时,提高易用性。整个专栏有 6 篇文章,感兴趣的朋友请加关注。
专栏目录

cglib bean copy 介绍。
mica bean copy 介绍和链式 bean copy 的支持。
mica bean 支持 copy 原始类型和封装类型。
mica bean 支持 copy map 到 bean。
使用 Spring 的类型转换增强 mica bean copy。
mica bean、Map 互转增强和总结。

Cglib BeanCopier 介绍
阿里巴巴 p3c 插件中有这么一项检查“避免用 Apache Beanutils 进行属性的 copy,Apache BeanUtils 性能较差,可以使用其他方案比如 Spring BeanUtils, Cglib BeanCopier”。今天我们的主角主要就是 Cglib 的 BeanCopier。

性能
下图是 github 上的一个 Bean copy 性能的对比,可以看出 Bean copy 工具性能差距还是比较大。
更多请见:https://github.com/yangtu222/BeanUtils#performance
图中可以看出,Cglib BeanCopier 的性能十分强劲,也难怪阿里巴巴规范中也推荐,下面我们来看看它具体的使用方式。
使用
Cglib 以源码的形式纳入到 Spring core 中,所有大家使用 Spring、Spring boot 可以直接使用。其它则需要自己添加依赖,下面的使用例子都以 Spring 的为主。注意:使用了 Lombok。
User 对象
@Data
public class User {
private Integer id;
private String name;
private Integer age;
}
UserVo 对象
@Data
public class UserVo {
private String name;
private Integer age;
}
Bean 拷贝
import org.springframework.cglib.beans.BeanCopier;

public class UserCopyTest {

public static void main(String[] args) {
// 1. 初始化 user,赋值
User user = new User();
user.setId(250);
user.setName(“ 如梦技术 ”);
user.setAge(30);

// 2. 初始化 userVo
UserVo userVo = new UserVo();
// 3. 构造 BeanCopier,不是用类型转换
BeanCopier copier = BeanCopier.create(User.class, UserVo.class, false);
// 4. 拷贝对象,不是用类型转换,转换器可以使用 null
copier.copy(user, userVo, null);

// 5. 打印结果:UserVo(name= 如梦技术, age=30)
System.out.println(userVo);
}
}
原理
大家都知道 Cglib BeanCopier,之所以性能这么高主要是利用了 Asm 字节码技术。
在 UserCopyTest 的 main 方法中添加下面的代码(建议直接放置到 1. 初始化 user,赋值 之前),指定 cglib 源码生成目录,建议生成到 idea 项目中,可以直接打开生成的 class 字节码。
// 设置 cglib 源码生成目录
String sourcePath = “/Users/lcm/git/mica/mica-example/web-example/src/test/java”;
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, sourcePath);
再次执行 main 方法。我们可以看到控制台打印下了这么一行日志。
CGLIB debugging enabled, writing to ‘/Users/lcm/git/mica/mica-example/web-example/src/test/java’
下面我们来看看生成的代码:
看到此图大家恍然大悟,Cglib BeanCopier 帮我们生成了 get set 转换。
Cglib copy 问题

不支持链式 bean,mybatis-plus 生成的 Model 中默认添加了 @Accessors(chain = true) 注解默认为链式。
不支持 原始类型和封装类型 copy int <-> Integer。
类型转换不够智能,设置 useConverter 为 true 和重写 Converter,类型相同也会走转换的逻辑。

注意:这部分后面会详细介绍,喜欢的朋友请关注、订阅我们。

链接
mica:https://github.com/lets-mica/mica 如梦技术官网:https://www.dreamlu.net
开源推荐

Spring boot 微服务高效开发 mica 工具集:https://gitee.com/596392912/mica

Avue 一款基于 vue 可配置化的神奇框架:https://gitee.com/smallweigit/avue

pig 宇宙最强微服务(架构师必备):https://gitee.com/log4j/pig

SpringBlade 完整的线上解决方案(企业开发必备):https://gitee.com/smallc/SpringBlade

IJPay 支付 SDK 让支付触手可及:https://gitee.com/javen205/IJPay

加入【如梦技术】Spring QQ 群:479710041,了解更多。

关注我们
扫描上面二维码,更多精彩内容每天推荐!

退出移动版