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

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

专栏介绍

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

专栏目录

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

Cglib BeanCopier 介绍

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

性能

下图是 github 上的一个 Bean copy 性能的对比,可以看出 Bean copy 工具性能差距还是比较大。
11111111.png

更多请见: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'

下面我们来看看生成的代码:
1111.png

看到此图大家恍然大悟,Cglib BeanCopier 帮我们生成了 get set 转换。

Cglib copy 问题

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

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

链接

mica:https://github.com/lets-mica/mica
如梦技术官网:https://www.dreamlu.net

开源推荐

目录
相关文章
|
1月前
|
Java Linux iOS开发
Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
27 0
|
Java Spring
Spring 源码阅读 61:基于 JDK 动态代理的 AOP 代理回调方法 invoke 分析
本文分析了 JdkDynamicAopProxy 的invoke方法,invoke方法是基于 JDK 动态代理创建的 AOP 代理对象的方法处理回调逻辑,也是 Spring AOP 增强目标方法的关键逻辑。
231 0
Spring 源码阅读 61:基于 JDK 动态代理的 AOP 代理回调方法 invoke 分析
|
设计模式 Java 编译器
Spring AOP【AOP的基本实现与动态代理JDK Proxy 和 CGLIB区别】
Spring AOP【AOP的基本实现与动态代理JDK Proxy 和 CGLIB区别】
Spring AOP【AOP的基本实现与动态代理JDK Proxy 和 CGLIB区别】
|
Java Spring
Spring 源码阅读 60:通过 JDK 动态代理或者 CGLIB 创建 AOP 代理对象
本文分别分析了 Spring 通过 JDK 动态代理和 CGLIB 两种方式创建 AOP 代理对象的过程。至此,Spring AOP 特性中,代理对象创建的全部过程就分析完了。
174 0
Spring 源码阅读 60:通过 JDK 动态代理或者 CGLIB 创建 AOP 代理对象
|
Java Spring
Spring 源码阅读 59:确定创建 AOP 代理的方式是 JDK 动态代理还是 CGLIB
本文进入createProxy方法,分析了 Spring 创建代理对象的大致过程,以及如何选择 JDK 动态代理或者 CGLIB 方式来创建代理对象。
155 0
Spring 源码阅读 59:确定创建 AOP 代理的方式是 JDK 动态代理还是 CGLIB
|
Java Spring
Spring系列七:JDK 动态代理和 CGLIB 代理
​ 21.说说JDK 动态代理和 CGLIB 代理 ? Spring的AOP是通过动态代理来实现的,动态代理主要有两种方式JDK动态代理和Cglib动态代理,这两种动态代理的使用和原理有些不同。 JDK 动态代理 CgLib 动态代理 我们来看一个常见的小场景,客服中转,解决用户问题: 用户向客服提问题 JDK动态代理实现: JDK动态代理类图 public interface ISolver {     void solve(); } public class Solver implements ISolver {     @Override     pu
267 0
Spring系列七:JDK 动态代理和 CGLIB 代理
|
Java Spring 容器
【小家Spring】面向切面编程Spring AOP创建代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory(JDK Proxy和CGLIB)(上)
【小家Spring】面向切面编程Spring AOP创建代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory(JDK Proxy和CGLIB)(上)
【小家Spring】面向切面编程Spring AOP创建代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory(JDK Proxy和CGLIB)(上)
|
缓存 Java Spring
【小家Spring】面向切面编程Spring AOP创建代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory(JDK Proxy和CGLIB)(中)
【小家Spring】面向切面编程Spring AOP创建代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory(JDK Proxy和CGLIB)(中)
|
缓存 Java Spring
【小家Spring】面向切面编程Spring AOP创建代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory(JDK Proxy和CGLIB)(下)
【小家Spring】面向切面编程Spring AOP创建代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory(JDK Proxy和CGLIB)(下)
|
XML 数据格式
SPRING03_AOP的概述、动态代理、cglib代理、相关概念、基于xml配置、基于注解配置(四)
SPRING03_AOP的概述、动态代理、cglib代理、相关概念、基于xml配置、基于注解配置(四)
SPRING03_AOP的概述、动态代理、cglib代理、相关概念、基于xml配置、基于注解配置(四)