cglib动态代理 | 如何生成代理类、代理类内容解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: cglib动态代理 | 如何生成代理类、代理类内容解析

简介

 CgLib(Code Generation Library)是一个针对java,且开源的代码生成类库,封装了ASM,ASM可以直接产生二进制class文件。CgLib能够在运行时动态地生成类的子类,常用于实现动态代理。


CGLib被广泛使用在基于代理的AOP框架(例如SpringAOP和dynaop)

hibernate使用CGLib对持久化对象创建代理。

本篇博客将从三个方面讲述:

  • cglib动态代理有什么优点
  • 如何生成代理类
  • 代理类内容解析

一、cglib动态代理有什么特点

特点 动态代理 静态代理
代理对象创建时间 运行时动态生成代理类 编码时编写代理类
代码维护 代理逻辑集中在一个通用的类中,易于维护和修改 代理逻辑分散在多个具体代理类中,增加了代码维护的复杂性

CgLib动态代理:

优点:

1.被代理的类不必须要实现一个接口,因为通过继承的方式重写被代理类方法

2.FastClass机制,不使用反射调用被代理方法,代码执行速度快

缺点:

1.无法重写的方法不能被cglib代理

2.生成代理类花费时间比较多,因为还要额外生成两个代理类(FastClass相关类),所以单例模式更适合cglib

二、Cglib如何生成代理类

  这就要涉及到源码了,Cglib提供生成的代理类的方式是调用Enhancer类的create方法,在创建代理类之前还有两个必要条件:

  1. superclass:被代理的类
  2. callback:设置回调的拦截器
    //生成一个增强器
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserService.class); //设置要代理的类
        enhancer.setCallback(new MyApiInterceptor()); //设置回调的拦截器数组
        // 创建代理对象
        Person person=enhancer.create();
        person.test();

  拦截器:

class MyApiInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("被代理方法执行前"); // 此处可以做一些操作
        Object result = proxy.invokeSuper(obj, args);//执行被代理方法
        System.out.println("被代理方法执行后" );  // 方法调用之后也可以进行一些操作
        return result;
    }
}

  被代理类:

class UserService {
  //方法必须能被重写,不能被final修饰
    public void test() {
        System.out.println("调用test方法了...");
    }
}

下面看Enhancer类的create方法做了什么:

1.调用Enhancer的createHelper()方法:

2.调用super.create(),也就是AbstractClassGenerator的create()方法:

  主要看下面的截图:data.get方法生成代理类、return那句返回了代理类对象。

生成代理类的具体代码:

  data.get是一个入口,主要看Enhancer的generate()方法

  以及Enhancer的generateClass()方法

  idea上写的java代码都是.java格式的,经过jvm的编译器编译会生成字节码文件(.class),Cglib使用asm直接生成字节码文件。字节码是由一条条的指令构成,专门学习过才看得懂,所以如何生成代理类不用过分关注,能看懂生成的代理类有哪些内容即可。


生成代理对象的具体代码:

Enhancer的createUsingReflection()方法

三、代理类内容解析

持久化代理类:

  Cglib生成的代理类放在内存中,通过dglib提供的调试命令可以将代理类持久化到硬盘。

-Dcglib.debugLocation=E:\project\common\CglibDemo\target\classes\   ##可以持久化到任意目录

重新启动程序执行代理逻辑,会发现指定路径生成了代理类:

代理类内容:

1.继承了Userservice类(被代理类)

2.重写了Userservice(被代理类)的test方法

3.重写了Object类能被重写的方法

Cglib动态代理和jdk动态代理

  CGLIB(Code Generation Library)和 JDK(Java Development Kit)中的动态代理是两种不同的实现方式,它们在实现原理和使用方式上存在一些区别。


原理:

 JDK动态代理是基于接口的代理。它使用Java的反射机制,在运行时创建一个实现指定接口的代理类。代理类实现了InvocationHandler接口,并将方法调用转发给InvocationHandler处理。

 CGLIB动态代理是基于继承的代理。它通过生成目标类的子类来实现代理。代理类继承了目标类,并重写了方法,从而实现了方法拦截和增强的功能。


使用方式:

 JDK动态代理要求目标类实现一个接口,代理对象实现了与目标类相同的接口。通过Proxy类的静态方法创建代理对象,将目标对象和InvocationHandler实例传入。

 CGLIB动态代理不要求目标类实现接口。通过Enhancer类创建代理对象,将目标对象设置为父类,同时设置MethodInterceptor实例作为拦截器。


性能:

 JDK动态代理在调用代理方法时,通过反射调用目标方法,因此会引入一定的性能开销。但对于接口代理,JDK动态代理是唯一的选择。

 CGLIB动态代理直接调用目标方法,省去了反射的开销,因此在性能上通常比JDK动态代理略快。但是对于final类、private方法和static方法等无法代理的情况,CGLIB无法生成代理类。

总结

  本篇文章带你了解cglib动态代理的外表,它的内部逻辑是如何实现的呢,还遗留了两个问题,博主会为cglib动态代理做一个系列的博客。

  • 问题1:代理类执行方法是如何被拦截的
  • 问题2:FastClass机制如何实现
目录
打赏
0
1
1
0
5
分享
相关文章
|
6天前
|
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
26 5
鸿蒙赋能智慧物流:AI类目标签技术深度解析与实践
在数字化浪潮下,物流行业面临变革,传统模式的局限性凸显。AI技术为物流转型升级注入动力。本文聚焦HarmonyOS NEXT API 12及以上版本,探讨如何利用AI类目标签技术提升智慧物流效率、准确性和成本控制。通过高效数据处理、实时监控和动态调整,AI技术显著优于传统方式。鸿蒙系统的分布式软总线技术和隐私保护机制为智慧物流提供了坚实基础。从仓储管理到运输监控再到配送优化,AI类目标签技术助力物流全流程智能化,提高客户满意度并降低成本。开发者可借助深度学习框架和鸿蒙系统特性,开发创新应用,推动物流行业智能化升级。
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
63 12
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。
【C++篇】深度解析类与对象(上)
在C++中,类和对象是面向对象编程的基础组成部分。通过类,程序员可以对现实世界的实体进行模拟和抽象。类的基本概念包括成员变量、成员函数、访问控制等。本篇博客将介绍C++类与对象的基础知识,为后续学习打下良好的基础。
代理协议解析:如何根据需求选择HTTP、HTTPS或SOCKS5?
本文详细介绍了HTTP、HTTPS和SOCKS5三种代理协议的特点、优缺点以及适用场景。通过对比和分析,可以根据具体需求选择最合适的代理协议。希望本文能帮助您更好地理解和应用代理协议,提高网络应用的安全性和性能。
60 17
团队管理者必读:高效看板类协同软件的功能解析
在现代职场中,团队协作的效率直接影响项目成败。看板类协同软件通过可视化界面,帮助团队清晰规划任务、追踪进度,提高协作效率。本文介绍看板类软件的优势,并推荐五款优质工具:板栗看板、Trello、Monday.com、ClickUp 和 Asana,助力团队实现高效管理。
89 2
动态代理与静态代理在爬虫解析的优缺点
随着科技和互联网的发展,越来越多企业需要使用代理进行数据抓取。本文介绍了HTTP动态代理与静态代理的区别,帮助您根据具体需求选择最佳方案。动态代理适合大规模、高效率的爬取任务,但稳定性较差;静态代理则适用于小规模、高稳定性和速度要求的场景。选择时需考虑目标、数据量及网站策略。
78 4
Spring AOP深度解析:探秘动态代理与增强逻辑
Spring框架中的AOP(Aspect-Oriented Programming,面向切面编程)功能为开发者提供了一种强大的工具,用以将横切关注点(如日志、事务管理等)与业务逻辑分离。本文将深入探讨Spring AOP的底层原理,包括动态代理机制和增强逻辑的实现。
86 4

热门文章

最新文章

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等