CGLIB动态代理详解分析

news2024/11/27 6:23:08

一、介绍

CGLIB是强大的、高性能的代码生成库,被广泛应用于AOP框架,它底层使用ASM来操作字节码生成新的类,为对象引入间接级别,以控制对象的访问。CGLIB相比于JDK动态代理更加强大,JDK动态代理只能对接口进行代理,而CGLIB既可以代理普通类,也能够代理接口。

优点:

  • 通过FastClass机制调用方法,比JDK动态代理的反射机制效率高;被代理类无需实现接口

缺点:

  • 运行期生成字节码,通过ASM写Class字节码,效率低;不能对final类及final方法进行代理

二、工作原理

g

CGLIB 通过动态生成一个需要被代理类的子类(即被代理类作为父类),该子类重写被代理类的所有不是 final 修饰的方法,并在子类中采用方法拦截的技术拦截父类所有的方法调用,进而织入横切逻辑。此外,因为 CGLIB 采用整型变量建立了方法索引,这比使用 JDK 动态代理更快(使用 Java 反射技术创建代理类的实例)。

2.1步骤说明-生成代理对象

  1. 创建要被代理的类或接口–MyFly
public class MyFly implements Fly {
    @Override
    public void doFly() {
        System.out.println("wo的");
    }
}
  1. 实现MethodInterceptor并实现intercept方法 --CglibProxy
class CglibProxy implements MethodInterceptor {
    /**
     * @param o:           代理对象
     * @param method:      被代理方法
     * @param params:      方法入参
     * @param methodProxy: CGLIB方法
     **/
    @Override
    public Object intercept(Object o, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
        System.out.println("【增强方法】代理对象正在执行的方法:" + method.getName());
        Object result = methodProxy.invokeSuper(o, params);
        return result;
    }
}
  1. 创建Enhancer(设置要被代理的类和调用方法时触发的拦截器)
 public static Object creatCglibProxyObj(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        // 为加强器指定要代理的业务类(即为下面生成的代理类指定父类)
        enhancer.setSuperclass(clazz);
        // 设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法
        enhancer.setCallback(new CglibProxy());
        return enhancer.create();
    }
  1. 执行程序
public static void main(String[] args) {
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\class");
        Fly fly = (Fly) CglibProxyFactory.creatCglibProxyObj(MyFly.class);
        fly.doFly();
    }

结果:
在这里插入图片描述

2.2 代理对象分析

通过设置属性来输出生成的代理对象

System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\class");

在这里插入图片描述
通过IDEA打开class文件

2.2.1表头分析

在这里插入图片描述

结论:

  1. 生成的代理对象继承了我们需要被代理的对象同时实现了Factory
  2. 这里是通过继承的方式来代理的,所以他即可以代理类也可以代理接口
  3. 因为是继承了被代理类,所以在java中子类是无法重写父类final方法的,这也就解释了为什么CGLIB无法代理final修饰的方法了

2.2.2 stataic 静态代码块

在这里插入图片描述

结论:

  1. 这里面创建了一些后续要试用的变量引用

2.2.3 重写父类方法

在这里插入图片描述

结论:

  1. 重写的方法被final,防止后面被修改
  2. 这里的var10000就是我们在创建代理时传入的CglibProxy
  3. 这里也就解释了CGLIB是如何动态增强方法的基本逻辑(在每次调用方法时都会先去调用MethodInterceptor的实现类中的intercept方法,然后我们只需要在intercept方法中实现要加强的代码即可)

2.3 代理方法调用过程分析

2.2.3 调用代理方法

在这里插入图片描述

结论:

  1. 创建代理对象fly
  2. 通过调用代理对象fly.doFly()方法
    在这里插入图片描述
    3. 调用MethodInterceptor的intercept方法,这里就是调用我们的CglibProxy
    在这里插入图片描述
    4. 调用methodProxy.invokeSuper(o, params);这里就是要调用被代理类的原始方法
    在这里插入图片描述
  3. 通过init()来初始化生成代理类和被代理类的FastClass
    在这里插入图片描述
helper:在这里插入图片描述
  1. 生成的FastClass文件
    在这里插入图片描述
  2. 生成的FastClass文件的invoke方法
    在这里插入图片描述
  3. init完成后这里会继续调用fci.f2.invoke(fci.i2, obj, args);
  • 这里的fci.f2就是刚刚生成的代理对象FastCalss对象在这里插入图片描述
  • 这里程序会传入17,调用代理类的CGLIB$doFly$0()方法;(大家可以debug看,每次生成的文件位置会不一样)
    在这里插入图片描述
  1. 调用代理类的CGLIB$doFly$0()
    • 到这里基本可以知道它是如何帮助我们调用被代理类的方法了
    • 这里的super指的就是MyFly,因为CGLIB生成的代理类继承了我们要被代理的类
      在这里插入图片描述

结束

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

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

相关文章

Django中如何正确使用 redis 如何在 Heroku 部署 Django时使用 Redis

文章目录 问题起源&#xff1a;AsyncWebsocketConsumer 中的 channel_layer解决方案安装 & 启动 redis安装 channel-redis更新 settings.py 的 redis 设置 Heroku 部署add-on 添加 Redis 组件settings.py 问题起源&#xff1a;AsyncWebsocketConsumer 中的 channel_layer 在…

真的不想搞清楚音频转换成mp3免费软件有哪些

曾经有一个音乐制作人&#xff0c;他有很多高质量的音频文件&#xff0c;但是他需要将它们转换成mp3格式才能分享给更多人。然而&#xff0c;他不想花费大量的金钱购买昂贵的软件。于是他开始寻找免费的音频转换软件&#xff0c;希望能够搞清楚音频转换成mp3免费软件有哪些。经…

SpringBoot教学资料5-SpringBoot一对多查询(带简单前端)

项目展示&#xff1a; 项目结构&#xff1a; SQL&#xff1a; CREATE TABLE t_article (id int(20) NOT NULL AUTO_INCREMENT COMMENT 文章id,title varchar(200) DEFAULT NULL COMMENT 文章标题,content longtext COMMENT 文章内容,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCR…

自制交流自动稳压器电路设计

目前在我国偏远的山区及农村&#xff0c;电网电压极不稳定&#xff0c;而且电压普遍偏低&#xff0c;有的电网电压只有 120V 左右。在这样的电网中&#xff0c;电视机及其它家用电器就无法正常使用了。市场上虽有较多的稳压器&#xff0c;但使用起来效果并不怎么好&#xff0c;…

Stable Diffusion 中Civitai站点模型管理助手

对于AI画画的读者来说&#xff0c;一旦开始使用Stable Diffusion&#xff0c;看到未曾使用过的模型&#xff0c;无法抑制下载的冲动。然而随着模型的堆积&#xff0c;整理及选择变得困难。此时Civitai Helper来解决这个问题。 文章目录 Civitai Helper插件安装模型信息模型更新…

Python WSGI 与 Web 开发框架

目录 文章目录 目录WSGIWSGI 的工作原理environ 参数start_resposne 参数 WSGI 的中间件 WSGI Web 开发框架OpenStack 中的应用案例进程入口WSGI Application 加载Paste/PasteDeployRoutesWebOb WSGI Server 启动 WSGI WSGI&#xff08;Web Server Gateway Interface&#xff…

【UE 材质】磨砂玻璃材质

效果 步骤 新建一个材质&#xff0c;这里命名为“M_FrostedGlass” 打开“M_FrostedGlass”&#xff0c;设置混合模式为半透明 添加如下节点&#xff1a; 创建一个材质实例 将材质实例赋予到一个mesh 打开材质实例&#xff0c;调整一下玻璃颜色和模糊值 原视频链接&#xff1a…

微信小程序UV、PV量解释以及接口调用频率

微信小程序UV、PV量 浏览量(PV)&#xff1a;即通常说的Page View(PV)&#xff0c;用户每打开一个网站页面就被记录1次。用户多次打开同一页面&#xff0c;浏览量值累计。微信小程序中PV是打开小程序的打开次数。 访客数(UV)&#xff1a;一天之内网站的独立访客数(以Cookie为依…

建立LIS系统需注意解决的问题

建立LIS需注意解决的问题 数据接收的可靠性&#xff1a;不管是采用硬件方式还是软件方式接收数据&#xff0c;保证接收过程数据不丢失或出现错误&#xff0c;是建立LIS首先要解决好的技术问题&#xff0c;否则就不是一个成功的LIS&#xff0c;缺乏实际的应用价值。 系统运行的…

vue3+vite使用particles.js

上效果&#xff1a; 1、安装vue3-particles 注意&#xff1a; 这里不能直接安装2.0以上的版本&#xff0c;否则界面无法出来。至于根本原因目前还没查到 # 通过以下命令可以发现当前所具有的版本 $ pnpm view vue3-particles versions [1.42.1, 1.42.2, 1.42.3, 1.42.4,1.43.…

【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(场景问题分析+性能影响因素)

一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战&#xff08;场景问题分析性能影响因素&#xff09; 常见的几个场景问题问题1&#xff1a;过期还是不过期缓存数据保证最终一致性 问题2&#xff1a;维度化缓存与增量更新通过维度化缓存优点和好处 问题3…

总在谈流程,却又做不好,问题出在哪?

时至今日&#xff0c;流程这个概念无论是在理论层面还是实践层面&#xff0c;都已为大家所熟知。 特别是随着华为的崛起&#xff0c;流程的吸引力与日俱增&#xff0c;为数不少的企业都在服用流程这剂灵丹妙药。 可是&#xff0c;真正搞明白流程概念的企业还不算多&#xff0…

win10开启远程桌面,win10开启3389端口

文章目录 前言一、不能远程桌面的原因1.1、系统设置未开启远程桌面功能1.2、开启防火墙3389端口1.3、开启3389端口 二、开启3389端口2.1、查看是否开启端口2.2、启动远程桌面服务2.3、远程连接administrator账号提示由于账户限制无法登录 三、其他 前言 最近重装了一下小主机系…

Unity 非父子物体保持相对静止

非父子物体保持相对静止 &#x1f354;效果&#x1f96a;食用 &#x1f354;效果 保持两个非父子关系的物体坐标、旋转相对静止 &#x1f96a;食用 插件下载 using System.Collections; using System.Collections.Generic; using UnityEngine;namespace ZYF {public class…

IntelliJ IDEA路径里面的反斜杠变成了其他符号解决办法

IntelliJ IDEA里面配置任何路径的时候路径里面的反斜杠分隔符变成了其他符号解决办法。 问题如图&#xff1a; 路径都变成了W加删除线。 原因&#xff1a; 字体设置问题&#xff0c;字体把斜杠转义了。 解决&#xff1a; 别用Gothic的相关字体&#xff0c;换成其他字体即…

如何在可视化页面中保证数据安全?Sugar BI通过URL参数标识用户,灵活实现用户权限

公开分享之后的大屏/报表页面中&#xff0c;由于不需要用户登录账号&#xff0c;因此页面中 数据模型的行级别权限、SQL 建模中嵌入用户邮箱、API 后端获取当前登录用户 这些需要用户登录账号才能进行的权限限制功能都不可用。 但是在一些场景下&#xff0c;是期望这些权限功能…

滴水逆向三期笔记与作业——02C语言——04 IF语句逆向分析上

OneNote防丢失。 海哥牛逼。 IF语句逆向分析上 一、内存图二、如何判断函数的参数2.1 一般情况 三、if的汇编案例根据汇编还原if 四、作业 一、内存图 二、如何判断函数的参数 2.1 一般情况 三、if的汇编 案例 根据汇编还原if 四、作业 海哥牛逼。

macbook安装chatglm2-6b

1、前言 chatglm安装环境还是比较简单的&#xff0c;比起Stable diffusion安装轻松不少。   安装分两部分&#xff0c;一是github的源码&#xff0c;二是Hugging Face上的模型代码&#xff1b;安装过程跟着官方的readme文档就能顺利安装。以下安装内容&#xff0c;绝大部分是…

自然语言处理:多层感知机MLP和Word2vec

文章目录 多层感知机MLP1.神经网络2.反向传播算法3.激活函数4.损失函数5.神经网络的使用场景 Word2vec参考 多层感知机MLP 1.神经网络 神经网络是一种计算模型&#xff0c;它受到人脑神经元之间连接和信息处理方式的启发。它由许多简单的处理单元&#xff08;称为神经元或节点…

初始Liunx线程

文章目录 前言1.初始Liunx下线程2.关于虚拟地址的补充知识3.线程的相关特点1.线程的优点2.线程的缺点3.线程异常4.线程和进程的比较 4.线程相关操作接口线程控制相关接口 5.关于线程id的理解 前言 本文主要是对Liunx之下线程的前置知识铺垫&#xff0c;同时也是对之前进程的相…