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

简介: 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机制如何实现
相关文章
|
7月前
|
Java 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
241 0
|
8月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
10月前
|
数据可视化 数据挖掘 BI
团队管理者必读:高效看板类协同软件的功能解析
在现代职场中,团队协作的效率直接影响项目成败。看板类协同软件通过可视化界面,帮助团队清晰规划任务、追踪进度,提高协作效率。本文介绍看板类软件的优势,并推荐五款优质工具:板栗看板、Trello、Monday.com、ClickUp 和 Asana,助力团队实现高效管理。
195 2
|
7月前
|
存储 监控 安全
重学Java基础篇—类的生命周期深度解析
本文全面解析了Java类的生命周期,涵盖加载、验证、准备、解析、初始化、使用及卸载七个关键阶段。通过分阶段执行机制详解(如加载阶段的触发条件与技术实现),结合方法调用机制、内存回收保护等使用阶段特性,以及卸载条件和特殊场景处理,帮助开发者深入理解JVM运作原理。同时,文章探讨了性能优化建议、典型异常处理及新一代JVM特性(如元空间与模块化系统)。总结中强调安全优先、延迟加载与动态扩展的设计思想,并提供开发建议与进阶方向,助力解决性能调优、内存泄漏排查及框架设计等问题。
270 5
|
7月前
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
195 1
|
7月前
|
监控 负载均衡 安全
静态IP代理与动态IP代理:提升速度与保障隐私的技术解析
本文探讨了静态IP代理和动态IP代理的特性和应用场景。静态IP代理通过高质量服务提供商、网络设置优化、定期更换IP与负载均衡及性能监控提升网络访问速度;动态IP代理则通过隐藏真实IP、增强安全性、绕过封锁和提供独立IP保障用户隐私。结合实际案例与代码示例,展示了两者在不同场景下的优势,帮助用户根据需求选择合适的代理服务以实现高效、安全的网络访问。
217 1
|
7月前
|
传感器 监控 Java
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
257 5
|
8月前
|
Java 数据库 开发者
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
823 12
|
8月前
|
缓存 安全 网络安全
代理协议解析:如何根据需求选择HTTP、HTTPS或SOCKS5?
本文详细介绍了HTTP、HTTPS和SOCKS5三种代理协议的特点、优缺点以及适用场景。通过对比和分析,可以根据具体需求选择最合适的代理协议。希望本文能帮助您更好地理解和应用代理协议,提高网络应用的安全性和性能。
389 17
|
7月前
|
机器学习/深度学习 人工智能 监控
鸿蒙赋能智慧物流:AI类目标签技术深度解析与实践
在数字化浪潮下,物流行业面临变革,传统模式的局限性凸显。AI技术为物流转型升级注入动力。本文聚焦HarmonyOS NEXT API 12及以上版本,探讨如何利用AI类目标签技术提升智慧物流效率、准确性和成本控制。通过高效数据处理、实时监控和动态调整,AI技术显著优于传统方式。鸿蒙系统的分布式软总线技术和隐私保护机制为智慧物流提供了坚实基础。从仓储管理到运输监控再到配送优化,AI类目标签技术助力物流全流程智能化,提高客户满意度并降低成本。开发者可借助深度学习框架和鸿蒙系统特性,开发创新应用,推动物流行业智能化升级。
207 1

热门文章

最新文章

推荐镜像

更多
  • DNS