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

news2025/1/15 16:55:33

文章目录

  • 简介
    • 一、cglib动态代理有什么特点
      • CgLib动态代理:
        • 优点:
        • 缺点:
    • 二、Cglib如何生成代理类
      • 生成代理类的具体代码:
      • 生成代理对象的具体代码:
    • 三、代理类内容解析
      • 持久化代理类:
      • 代理类内容:
    • Cglib动态代理和jdk动态代理
  • 总结

简介

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

  1. CGLib被广泛使用在基于代理的AOP框架(例如SpringAOP和dynaop)
  2. 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机制如何实现
    在这里插入图片描述
    如果觉得有用就点个赞吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/679076.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据指标体系建设

一、什么是数据指标体系? 指标体系是从不同维度梳理业务,把指标有系统的组织起来。简而言之,指标体系指标体系,所以一个指标不能叫指标体系,几个毫无关系的指标也不叫指标体系。指标体系就像是一个整体、一辆车&#…

MacOS Sonoma 14.0 (23A5276g) Beta2 带 OC 引导双分区黑苹果镜像

苹果今日向 Mac 电脑用户推送了 macOS 14 开发者预览版 Beta2 更新(内部版本号:23A5276g),本次更新距离上次发布隔了 15 天。 镜像下载: 微信公众号: macOS Sonoma 14.0 (23A5276g) Beta2 带 OC 引导双分…

【人工智能】— 深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化

【人工智能】— 深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化 深度神经网络训练训练深度神经网络参数共享 卷积神经网络(CNN)卷积多卷积核卷积全连接最大池化卷积池化拉平向量激活函数优化小结 深度神经网络训练 Pr…

罗大佑、把午睡打造成领域驱动设计创新-UMLChina建模知识竞赛第4赛季第6轮

DDD领域驱动设计批评文集 欢迎加入“软件方法建模师”群 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 只要最先答对前3题,即可获得本轮优胜。第4题为附加题,对错不影响优胜者的判定&am…

最优化系列 之 线性规划问题的灵敏度分析(1/6)

一、实验目的: 1. 掌握用MATLAB、LINGO 、EXCEL优化工具箱解线性规划的方法; 2. 练习建立实际问题的线性规划模型; 3. 掌握线性规划灵敏度分析原理; 4. 预习线性规划的灵敏度分析原理及方法。 二、实验内容 题目1:求解…

【spring cloud学习】2、Eureka服务注册与发现

前言 一套微服务架构的系统由很多单一职责的服务单元组成,而每个服务单元又有众多运行实例。由于各服务单元颗粒度较小、数量众多,相互之间呈现网状依赖关系,因此需要服务注册中心来统一管理微服务实例,维护各服务实例的健康状态…

终端基础知识

CLI、Terminal、Shell、Prompt 一、CLI CLI is the abbreviation of Command Line Interface. It’s a text-based way of interacting with a computer. 相比于图像界面提供的按钮,你可以使用一行命令来实现你想要的功能,比如说打开、关闭文件&…

Linux用户信息关键文件详解

passwd文件说明 /etc/passwd文件记录了Linux所有用户的信息,是系统的关键文件之一。 文件格式内容如上图。 文件中的条目以“:”为分隔符,各个字段记录的信息依次为: 第一个字段:记录用户名 第二个字段:值x表示该用…

如何做一份干净的git提交记录

背景 毕业工作有一些年头了,之前在写工作代码或者给开源项目贡献的时候,提交代码都不是很规范,甚至可以说十分的随意,想到什么就提交什么,根本没有管理提交记录的概念或者想法(当你身边的人都不怎么在意的…

基于SpringBoot+SpringCloud+vue的智慧养老平台设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

大数据企业开发全套流程

大数据企业开发基础流程 Linux命令 1 Hadoop(HDFSYarn)单机版环境搭建 Hadoop 是一个开源的分布式计算框架,由 HDFS(Hadoop Distributed File System)和 YARN(Yet Another Resource Negotiator)两个核心组件组成。HD…

网络安全的含义及特征

网络安全从其本质上讲就是网络上的信息安全,指网络系统的硬件、软件及数据受到保护。不遭受破坏、更改、泄露,系统可靠正常地运行,网络服务不中断。从用户的角度,他们希望涉及到个人和商业的信息在网络上传输时受到机密性、完整性…

人人都能看懂的Spring源码解析,spring的事件监听机制

人人都能看懂的Spring源码解析,spring的事件监听机制 原理解析事件监听机制ApplicationEventPublisher、ApplicationEventMulticaster、ApplicationEvent、ApplicationListenerAbstractApplicationContext发布的事件类型 代码走读总结 往期文章: 人人都…

大数据Doris(四十八):Steam Load案例和注意事项

文章目录 Steam Load案例和注意事项 一、Steam Load案例 1、准备数据 2、创建 Doris 表 3、创建 Stream Load 导入任务 4、查看任务 5、查询Doris 表结果 二、注意事项 Steam Load案例和注意事项 一、Steam Load案例 下面以导入Linux节点本地磁盘数据到Doris为例&…

Python小游戏集合(开源、开源、免费下载)

Python小游戏集合 0. 前言1. 为什么用Python做游戏2. 小游戏集合及源代码(整理不易,一键三连)2.1 外星人小游戏2.2 塔防小游戏2.3 三国小游戏2.4 打飞机游戏2.5 飞机大战小游戏2.6 玛丽快跑小游戏2.7 涂鸦跳跃小游戏2.8 猜数字小游戏2.9 坦克…

金蝶云星空财务账套数据库中了.locked勒索病毒的解密步骤和预防方式

最近,金蝶云星空财务账套的数据库遭到了一次严重的勒索病毒攻击,导致数据库中重要数据被加密。这种攻击对企业来说是一种巨大的威胁,因为数据是企业的核心资产之一。而此次攻击的病毒为.locked后缀勒索病毒,而locked勒索病毒在本月…

VUE L 生命周期 ⑩①

目录 文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持✨ V u e j s Vuejs Vuejs初见生面周期分析生命周期生命周期总结总结 文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持✨ ⡖⠒⠒⠒⠤⢄…

Spring 项目过程及如何使用 Spring

文章目录 1.创建 Spring 项目步骤1.1 创建 Maven 项目1.2添加 Spring 框架支持1.3 添加启动项2.如何使用 Spring2.1 存储 Bean 对象2.1.1 创建 Bean对象2.1.2 将 Bean对象注册到容器中 2.2 获取并使用 Bean对象2.2.1 使用 ApplicationContext 获取对象2.2.2 使用 BeanFactory 获…

五、Docker镜像发布到阿里云/私有库

学习参考:尚硅谷Docker实战教程、Docker官网、其他优秀博客(参考过的在文章最后列出) 目录 前言一、本地镜像发布到阿里云1.1 流程图1.2 注册阿里云创建容器服务个人实例1.3 创建命名空间1.4 创建镜像仓库1.5 将镜像推送到阿里云本地仓库 二、从阿里云仓库拉去自己推…

Matlab统计分析 -- 聚类算法模型

统计分析 – 聚类算法模型 距离分析 数据标准化 欧氏距离与量纲有关,因此,有时需要对数据进行预处理, 如标准化等。 在MATLAB中的命令是zscore,调用格式 Z zscore(X) 输入X表示N行p列的原始观测矩阵,行为个体&…