Spring5应用之Cglib动态代理

作者简介:☕️大家好,我是Aomsir,一个爱折腾的开发者!
个人主页:Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客
当前专栏:Spring5应用专栏_Aomsir的博客-CSDN博客

文章目录

  • 前言
  • Cglib动态代理
    • 开发步骤
  • 总结
  • 参考文献

前言

在上一篇文章中,我讲述了Spring动态代理底层具体实现之一的JDK动态代理,并在结尾抛出了本篇文章将要讲述的内容,本篇文章我将会着手于Spring动态代理底层具体实现的另一门技术之Cglib

Cglib动态代理

在上一章关于JDK动态代理的讨论中,我们确实注意到了其一个明显的限制:原始类和代理类都必须实现同一个接口,代理类方法添加额外功能并调用原始类方法。这种方式就像房屋中介:他们为租客提供服务,而租客可能并不知道背后的真正房东。但这种模式确实存在局限性,特别是当我们的系统设计中没有采用接口,或者原始类并没有实现任何接口而是直接写具体方法实现时

那么,面对这种情况,我们怎么办?我们如何实现动态代理而不受到"必须实现接口"这一限制的约束?为了解决这个问题,Cglib(Code Generation Library) 应运而生。Cglib为我们提供了一种不基于接口的代理实现方式,它可以直接代理类。相对于JDK的代理方式,Cglib是基于继承父类(原始类)的,它会动态生成一个子类来覆盖原始类的方法,从而实现代理功能。这样既可以保证二者方法一致,这样既可以保证在代理类中提供新的实现,同时又调用了原始方法

这种方法提供了更大的灵活性,特别是对于那些没有接口的类。在接下来的章节中,我们将深入探讨Cglib,了解它是如何提供这种强大功能的,以及它与JDK动态代理的区别和优缺点

开发步骤

使用Cglib创建动态代理的过程在逻辑上与JDK动态代理非常相似,但主要差异在于原始类不需要实现任何接口。以下是具体的步骤:

  1. 原始类的设计:首先,我们要设计并定义一个原始类。特别要注意的是,这里的原始类无需实现任何接口。这为那些基于纯类设计而非接口设计的应用提供了方便。
  2. 定义增强功能:就像在JDK动态代理中一样,您需要确定您希望添加到原始类中的额外或增强功能。
  3. 生成动态代理对象:使用Cglib的Enhancer对象可以为上一步中定义的原始类生成动态代理对象。为了实现此过程,确保项目中包含了Cglib的必要依赖。幸运的是这些依赖已经包含在spring-context库中,从而简化了集成过程
    在这里插入图片描述
public class UserService {private static final Logger log = LoggerFactory.getLogger(UserService.class);public void login(String name, String password) {log.info("name = {}, password = {}", name, password);}public void register(User user) {log.info("{}", user);}
}
public class TestCglibProxy {private static final Logger log = LoggerFactory.getLogger(TestCglibProxy.class);@Testpublic void test1() {// 创建原始对象UserService userService = new UserService();// 创建Cglib提供的Enhancer对象,用于设置好创建代理对象Enhancer enhancer = new Enhancer();// 设置类加载器enhancer.setClassLoader(TestCglibProxy.class.getClassLoader());// 设置被代理类(原始父类)enhancer.setSuperclass(UserService.class);// 设置方法拦截器MethodInterceptor methodInterceptor = new MethodInterceptor() {// 等同于InvocationHandler中的invoke方法@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {log.debug("log before");Object ret = method.invoke(userService, objects);log.debug("log after");return ret;}};enhancer.setCallback(methodInterceptor);// 创建代理对象UserService userServiceProxy = (UserService) enhancer.create();userServiceProxy.login("Aomsir", "123456");}
}

总结

经过前两篇文章的深入探讨,我们对Spring动态代理的底层实现有了更为全面的了解。其中,JDK动态代理和Cglib动态代理是两种最为核心的技术手段。

JDK动态代理以接口为核心,通过Proxy.newInstance()方法为我们提供了创建代理对象的能力,要求原始类必须实现某个接口。而Cglib动态代理则更为灵活,不受接口的限制。通过Enhancer.create(),它直接生成原始类的子类,并在其中嵌入额外功能,从而实现代理。当然我们也可以通过设置让Spring在创建的时候只使用Cglib而不使用JDK

Spring AOP聪明地整合了这两种机制,为开发者提供了无缝的体验。它默认采用JDK动态代理,但当遇到没有实现接口的原始类时,会智能切换到Cglib动态代理

现在,再回过头来重新审视 BeanPostProcessor,我们可以发现更多之前可能忽略的细节和深层次的关联。正是这些细节和关联,使得Spring AOP的实现如此高效且灵活,满足了开发者的各种需求

<aop:config proxy-target-class="true">
</aop:config>

参考文献

  • 孙哥孙帅suns说Spring5~学不会Spring? 因为你没找对人
  • Spring官方文档

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

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

相关文章

uCOSIII实时操作系统 二 同步与通信

目录 同步概念&#xff1a; 互斥概念&#xff1a; 临界区概念&#xff1a; 任务时间概念&#xff1a; 信号量概念&#xff1a; 互斥信号量概念&#xff1a; 事件标志组概念&#xff1a; 消息邮箱和消息梯队概念&#xff1a; 内存管理概念&#xff1a; 如何从裸机开发…

矢量图形编辑软件illustrator 2023 mac特点介绍

illustrator 2023 mac是一款矢量图形编辑软件&#xff0c;用于创建和编辑排版、图标、标志、插图和其他类型的矢量图形。 illustrator mac软件特点 矢量图形&#xff1a;illustrator创建的图形是矢量图形&#xff0c;可以无限放大而不失真&#xff0c;这与像素图形编辑软件&am…

六、vpp 流表+负载均衡

草稿&#xff01;&#xff01;&#xff01; vpp node其实就是三个部分 1、plugin init 2、set command 3、function 实现功能&#xff0c;比如这里的流表 今天我们再用VPP实现一个流表的功能 一、流表 1.1流表----plugin init VLIB_REGISTER_NODE 注册流表节点 // 注册流…

纯css实现3D鼠标跟随倾斜

老规矩先上图 为什么今天会想起来整这个呢?这是因为和我朋友吵架, 就是关于这个效果的,就是这个 卡片懸停毛玻璃效果, 我朋友认为纯css也能写, 我则坦言他就是在放狗屁,这种跟随鼠标的3D效果要怎么可能能用纯css写, 然后吵着吵着发现,欸,好像真能用css写哦,我以前还写过这种…

去雨去雪去雾数据集构建

在进行去雨去雪去雾算法的学习过程中&#xff0c;需要构建去雨去雪去雾数据集&#xff0c;本文参考Learning Multiple Adverse Weather Removal via Two-stage Knowledge Learning and Multi-contrastive Regularization: Toward a Unified Model论文中的数据集设定&#xff0c…

面试题 17.24. 最大子矩阵

链接&#xff1a; 面试题 17.24. 最大子矩阵 题解&#xff1a; 这样我们就将二维问题转化为了一维问题&#xff0c;现在另一个问题就是怎么把所有情况都遍历到呢&#xff1f; 我们以第i行为第一行&#xff0c;向下延申&#xff0c;设最后一行为第j行&#xff0c;我们就i在这么…

【AI视野·今日NLP 自然语言处理论文速览 第四十七期】Wed, 4 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 4 Oct 2023 Totally 73 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Contrastive Post-training Large Language Models on Data Curriculum Authors Canwen Xu, Corby Rosset, Luc…

手机或者电脑连接局域网内的虚拟机(网桥)

手机或者电脑连接局域网内的虚拟机&#xff08;网桥&#xff09; 手机软件&#xff1a;ConnectBot&#xff0c;Termius&#xff0c;JuiceSSH … 1.虚拟机vmware中添加桥接网卡 这里桥接网卡选择的是自动&#xff0c;是自动生成动态IP&#xff0c;如果不需要动态生成&#xff…

MySQL:数据库的物理备份和恢复-冷备份(3)

介绍 物理备份&#xff1a; 直接复制数据文件进行的备份 优点&#xff1a;不需要其他的工具&#xff0c;直接复制就好&#xff0c;恢复直接复制备份文件即可 缺点&#xff1a;与存储引擎有关&#xff0c;跨平台能力较弱 逻辑备份&#xff1a; 从数据库中导出数据另存而进行的备…

性能测试工具 - LoadRunner

什么是性能测试&#xff1f; 性能测试就是测试人员利用性能测试工具模拟系统在不同情况下的性能指标是否正常。 性能测试工具 - LoadRunner 接下来介绍LoadRunner的作用和使用。 LoadRunner 就是一个很常见的性能测试工具&#xff0c;它有三个部分组成&#xff1a; 这三个组…

【MyBatis-Plus】快速精通Mybatis-plus框架—快速入门

大家在日常开发中应该能发现&#xff0c;单表的CRUD功能代码重复度很高&#xff0c;也没有什么难度。而这部分代码量往往比较大&#xff0c;开发起来比较费时。 因此&#xff0c;目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是…

Java实现微信支付

微信支付 小黄最在工作中对接需要对接微信支付&#xff0c;在此记录一下微信支付开发的相关流程&#xff0c;望能帮助到各位 前期准备 由于小黄是小程序端需要对接微信支付&#xff0c;需要注册小程序等&#xff0c;小黄会一一列举出来 小程序注册 所需文件 没有注册过微信…

私有云盘:lamp部署nextcloud+高可用集群

目录 一、实验准备&#xff1a; 二、配置mariadb主从复制 三台主机下载mariadb 1&#xff09;主的操作 2&#xff09;从的操作 3&#xff09;测试数据是否同步 三、配置nfs让web服务挂载 1、安装 2、配置nfs服务器 3、配置web服务的httpd 4、测试 四、web 服务器 配…

排序篇(三)----交换排序

排序篇(三)----交换排序 1.冒泡排序 基本思想: ​ 通过不断地比较相邻的元素&#xff0c;将较大的元素往后移动&#xff0c;从而实现排序的目的。 具体的步骤如下&#xff1a; 从待排序的数组中选择相邻的两个元素进行比较&#xff0c;如果前一个元素大于后一个元素&#…

ParagonNTFSforMac_15.5.102中文版最受欢迎的NTFS硬盘格式读取工具

Paragon NTFS for Mac是一款可以为您轻松解决Mac平台上不能识别Windows通用的NTFS文件难题&#xff0c;这是一款强大的Mac读写工具&#xff0c;相信在很多时候&#xff0c;Mac用户需要对NTFS文件的移动硬盘进行写入&#xff0c;但是macOS系统默认是不让写入的&#xff0c;使用小…

Nginx与Spring Boot的错误模拟实践:探索502和504错误的原因

文章目录 前言502和504区别---都是Nginx返回的access.log和error.log介绍SpringBoot结合Nginx实战502 and 504准备工作Nginx配置host配置SpringBoot 502模拟access.logerror.log 504模拟access.logerror.log 500模拟access.logerror.log 总结 前言 刚工作那会&#xff0c;最常…

Jmeter基础篇

1.性能测试指标 【虚拟用户数】&#xff1a;线程用户 【并发数】&#xff1a;指在某一时间&#xff0c;一定数量的虚拟用户同时对系统的某个功能进行交互&#xff0c;一般通过集合点实现 【事务】:事务代表一个完整的功能&#xff0c;一个接口可以是事务&#xff0c;多个接口…

第八章 排序 三、希尔排序

目录 一、算法思想 二、例子 三、代码实现 五、验证 六、空间复杂度 七、时间复杂度 八、稳定性 一、算法思想 先追求表中元素部分有序&#xff0c;在逐渐逼近表中元素全部有序。 二、例子 1、我们要升序排列此表 2、取一个差值作为子表的划分的条件&#xff0c;希尔本…

医疗器械标准目录汇编2022版共178页(文中附下载链接!)

为便于更好地应用医疗器械标准&#xff0c;国家药监局医疗器械标准管理中心组织对现行1851项医疗器械国家和行业标准按技术领域&#xff0c;编排形成《医疗器械标准目录汇编&#xff08;2022版&#xff09;》 该目录汇编分为通用技术领域和专业技术领域两大类&#xff0c;通用…

【逐步剖C】-第十一章-动态内存管理

一、为什么要有动态内存管理 从我们平常的学习经历来看&#xff0c;所开辟的数组一般都为固定长度大小的数组&#xff1b;但从很多现实需求来看需要我们开辟一个长度“可变”的数组&#xff0c;即这个数组的大小不能在建立数组时就指定&#xff0c;需要根据某个变量作为标准。…