專欄介紹
本套專欄主要是介紹微服務核心框架 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,瞭解更多。
關注我們
掃描上面二維碼,更多精彩內容每天推薦!