JDK动态代理和CGLIB动态代理案例分析
JDK动态代理和CGLIB动态代理案例分析
JDK动态代理和CGLIB动态代理的实现原理如下:
-
JDK动态代理的实现原理:
- JDK动态代理是基于Java的反射机制实现的
- 实现一个继承
InvocationHandler接口的对象,重写invoke方法,invoke方法中可以在目标方法执行前后添加一些额外的逻辑,该对象负责处理代理对象的方法调用。 - 当使用JDK动态代理时,通过
Proxy类的newProxyInstance方法创建代理对象,需要传入三个参数,分别是目标对象的类加载器、接口列表和一个实现了`InvocationHandler`接口的对象。 - 在代理对象的方法被调用时,
InvocationHandler的invoke方法会被触发,通过反射机制调用目标对象的方法。
-
CGLIB动态代理的实现原理:
- CGLIB动态代理使用字节码增强技术实现。
- 在运行时,CGLIB通过继承目标对象的子类来创建代理对象。
- CGLIB通过操作字节码,在子类中重写目标对象的方法,并在重写的方法中添加额外的逻辑。
- 通过创建子类的实例作为代理对象,实现对目标对象方法的代理。
JDK动态代理适用于目标对象实现了接口的情况,而CGLIB动态代理适用于目标对象没有实现接口的情况。根据具体的需求和场景,选择合适的动态代理方式来实现代理功能。
JDK动态代理
当使用JDK动态代理时,我们需要以下步骤来实现代理:
1. 定义一个接口,例如`UserService`,并在接口中声明需要代理的方法。
public interface UserService {void saveUser(String username);
}
2. 创建一个实现了`InvocationHandler`接口的类,例如`UserInvocationHandler`,该类负责处理代理对象的方法调用。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class UserInvocationHandler implements InvocationHandler {private Object target;public UserInvocationHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method: " + method.getName());Object result = method.invoke(target, args);System.out.println("After method: " + method.getName());return result;}
}
3. 在主程序中使用`Proxy`类的`newProxyInstance`方法创建代理对象。
import java.lang.reflect.Proxy;public class JDKDynamicProxyExample {public static void main(String[] args) {UserService userService = new UserServiceImpl();UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),userService.getClass().getInterfaces(),new UserInvocationHandler(userService));proxy.saveUser("John");}
}
在以上代码中,我们首先创建了一个实现了`InvocationHandler`接口的类`UserInvocationHandler`,它接收一个目标对象作为参数。在`invoke`方法中,我们可以在目标方法调用前后添加额外的逻辑。
然后,在主程序中,我们创建了一个`UserService`的实现类对象`userService`,然后通过`Proxy.newProxyInstance`方法创建了一个代理对象。在创建代理对象时,我们传入了目标对象的类加载器、接口列表和一个实现了`InvocationHandler`接口的对象`UserInvocationHandler`。
最后,我们调用代理对象的方法`saveUser`,在方法调用前后,`invoke`方法中的逻辑会被触发。
这就是JDK动态代理的实现原理的一个简单示例。通过代理对象,我们可以在目标方法调用前后添加额外的逻辑,实现对目标对象方法的代理。
CGLIB动态代理
为了使用CGLIB动态代理,需要引入CGLIB库。以下是使用CGLIB动态代理的示例代码:
1. 首先,确保您的项目中引入了CGLIB库。您可以在Maven项目中添加以下依赖:
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>
2. 定义一个目标类`UserServiceImpl`,它是没有实现接口的普通类。
public class UserServiceImpl {public void saveUser(String username) {System.out.println("Saving user: " + username);}
}
3. 创建一个实现了`MethodInterceptor`接口的类`UserMethodInterceptor`,重写intercept方法,intercept方法中可以在目标方法执行前后添加一些额外的逻辑,该类负责处理代理对象的方法调用。
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class UserMethodInterceptor implements MethodInterceptor {public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before method: " + method.getName());Object result = proxy.invokeSuper(obj, args);System.out.println("After method: " + method.getName());return result;}
}
4. 在主程序中使用CGLIB来创建代理对象。
import net.sf.cglib.proxy.Enhancer;public class CGLIBDynamicProxyExample {public static void main(String[] args) {UserServiceImpl userService = new UserServiceImpl();UserServiceImpl proxy = (UserServiceImpl) Enhancer.create(userService.getClass(),new UserMethodInterceptor());proxy.saveUser("John");}
}
在以上代码中,我们首先创建了一个实现了`MethodInterceptor`接口的类`UserMethodInterceptor`,它负责处理代理对象的方法调用。在`intercept`方法中,我们可以在目标方法调用前后添加额外的逻辑。
然后,在主程序中,我们创建了一个`UserServiceImpl`的实例对象`userService`,然后通过`Enhancer.create`方法创建了一个代理对象。在创建代理对象时,我们传入了目标对象的类和一个实现了`MethodInterceptor`接口的对象`UserMethodInterceptor`。
最后,我们调用代理对象的方法`saveUser`,在方法调用前后,`intercept`方法中的逻辑会被触发。
这就是CGLIB动态代理的实现原理的一个简单示例。通过代理对象,我们可以在目标方法调用前后添加额外的逻辑,实现对目标对象方法的代理。
相关文章:
JDK动态代理和CGLIB动态代理案例分析
JDK动态代理和CGLIB动态代理案例分析 JDK动态代理和CGLIB动态代理的实现原理如下: JDK动态代理的实现原理: JDK动态代理是基于Java的反射机制实现的实现一个继承InvocationHandler接口的对象,重写invoke方法,invoke方法中可以在目…...
【数据结构-前缀哈希】力扣1124. 表现良好的最长时间段
给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格 大…...
电商平台产品ID|CDN与预渲染|前端边缘计算
技术实现 都是通过ID拿到属性,进行预渲染html,通过 oss 分发出去 详情页这种基本都是通过 ssr 渲染出来,然后上缓存 CDN 分发到边缘节点来处理,具体逻辑可以参考 淘宝——EdgeRoutine边缘计算(CDNServerless 边缘计算…...
LATTICE进阶篇DDR2--(4)DDR2 IP核总结
一、IP核的时钟框架 1片DDR2的接口是16位,且DDR2是双边沿读取的, 故当DDR2芯片的时钟为200M时,右侧DDR2芯片上的数据吞吐率为200M*2*16b,左侧数据吞吐率为200M*32b,左右两侧数据吞吐量相等。 根据上规律可知…...
windows下php安装kafka
下载zookeeper Kafka 依赖 Zookeeper 进行分布式协调,所以需要下载Zookeeper ,当然你也可以使用kafka包里自带的一个默认配置的 Zookeeper。这里我们单独下载一个 访问Zookeeper官方下载页面在页面中找到最新的稳定版本,点击相应的下载链接…...
【wiki知识库】09.欢迎页面展示(浏览量统计)SpringBoot部分
🍊 编程有易不绕弯,成长之路不孤单! 大家好,我是熊哈哈,这个项目从我接手到现在有了两个多月的时间了吧,其实本来我在七月初就做完的吧,但是六月份的时候生病了,在家里休息了一个月的…...
数据分析与应用:微信-情人节红包流向探索分析
目录 0 需求描述 1 红包发送方用户的基本信息缺失率有多高?(即有多少红包发送方用户无法在用户基本信息表中匹配? 2 哪一组红包金额的拒收率最高? 3、最受二线城市欢迎的红包金额为?(即发出次数最多) 4 北上广深 4 大城市中,哪座城市的男性用户发出的 520 红包比例…...
SQL,获取 ID 的历史状态
sas系统的表tb存储病人的医疗历史记录,当Visit_codeSurgery时表示手术,Visit_codeOffice表示咨询,每个病人有多条Visit_code,有时只有Surgery或只有Office:IdVisit_DateVisit_codeA305/15/2004SurgeryA302/5/2005Offic…...
阅文集团:摇不动的IP摇钱树
把IP当成摇钱树,要做“东方迪士尼” 今天我们聊——阅文集团 《热辣滚烫》《庆余年2》《与凤行》和《玫瑰的故事》很熟悉吧?影视“四连爆”, 阅文集团交出一份亮眼半年报,时隔两年,重启增长。 跟IP相关业务对收入贡献…...
ETL数据集成丨将SQL Server数据同步至Oracle的具体实现
一、背景 在构建企业级数据架构时,将SQL Server数据库的数据同步至数仓数据库(如Oracle)是一项至关重要的任务。这一过程不仅促进了跨系统数据的一致性与可用性,还为数据分析、商业智能以及决策支持系统提供了坚实的数据基础。 …...
20240814软考架构-------软考51-55答案解析
每日打卡题51-55答案 51、【2017年真题】 难度:一般 系统移植也是系统构建的一种实现方法,在移植工作中, 需要最终确定移植方法。 A.计划阶段 B.准备阶段 C.转换阶段 D.验证阶段 答案:A 解析: 移植工作大体上分为计划…...
JavaEE 的入门
1. 学习JavaEE Java EE(Java Platform Enterprise Edition), Java 平台企业版. 是JavaSE的扩展, ⽤于解决企业级的开 发需求, 所以也可以称之为是⼀组⽤于企业开发的Java技术标准. 所以, 学习JavaEE主要是学习Java在 企业中如何应⽤. 前⾯学习的是Java基础, JavaEE 主要学习Jav…...
vue3+ts 前端word文档下载文件时不预览直接下载方法(支持 doc / excel / ppt / pdf 等)
前端word文档下载文件时不预览直接下载方法支持 doc / excel / ppt / pdf 等 根据需要,要实现一个下载文档的需要 最简单的方法就是使用a标签 如果是相同域可以直接下载,但如果是不同域的,就会先打开一个预览页,在预览页再点下载…...
Java 空值与null 形参与实参学习
Java系列文章目录 文章目录 Java系列文章目录一、前言二、学习内容:三、问题描述四、解决方案:4.1 空值与null的区别4.1.1 空值(Empty Value)4.1.2 Null 4.2 形参与实参区别 五、总结:5.1 学习总结: 一、前…...
【QT常用技术讲解】QTableView添加QCheckBox、QPushButton
前言 QT展示列表信息的时候通常用到列表(比如用户信息、机构信息、设备信息等菜单),当需要对某列进行修改、删除操作时,就需要加入按钮(QPushButton),当需要对多列进行右键菜单操作时࿰…...
linux监控命令
在 Linux 中,有许多命令可以用于监控系统的性能和状态。以下是一些常用的监控命令及其用途: 1. top 和 htop top top 命令显示当前系统中运行的进程列表及其资源使用情况。 top htop htop 是 top 命令的增强版,提…...
SpringBoot入门笔记
本文是看黑马老师讲课视频学习笔记整理 目录 入门案例 基于IDEA联网 基于Springboot官网创建 基于阿里云创建项目 手工创建 隐藏文件 入门案例解析: parent编辑 starter 引导类 内嵌tomcat 入门案例 基于IDEA联网 RestController RequestMapping("/books&…...
python 华为od 单词接龙
sd[word,dd,da,dc,dword,d] # 计算出下一个接龙单词 def jl(sd,st):# sd.remove(st)sd list(set(sd))sends list(st)[-1]lg []sd.sort()for i in sd:if i.startswith(sends):lg.append((i, len(i)))if lg[]:return 0,0lg.sort(keylambda x: x[1],reverseTrue)maxlen lg[0][…...
Vue+Echart实现地图省市区三级下钻
采用在线地图数据,整体简约,扩展也方便 参考 <template><div><div ref"mapContainer" style"width: 100%; height: 600px;"></div><button click"goBack">返回上一级</button></…...
Apache Tomcat 信息泄露漏洞排查处理CVE-2024-21733)
一、漏洞描述 Apache Tomcat作为一个流行的开源Web服务器和Java Servlet容器并用于很多中小型项目的开发中。其中,Coyote作为Tomcat的连接器组件,是Tomcat服务器提供的供客户端访问的外部接口,客户端通过Coyote与服务器建立链接、发送请求并且接收响应。 近日发现Apache To…...
【Java】Java核心关键字:final、static、volatile、synchronized、transient(附《面试高频考点》)
文章目录Java 5大核心关键字5大关键字——对比表1. final 关键字定义作用使用场景实现原理注意事项2. static 关键字定义作用使用场景实现原理注意事项3. volatile 关键字定义作用使用场景实现原理注意事项4. synchronized 关键字定义作用使用场景实现原理注意事项5. transient…...
论文降AI率要花多少钱?2026主流降AI工具收费标准对比
论文降AI率要花多少钱?2026主流降AI工具收费标准对比 “降一次AI率要好几百,太贵了吧?” “隔壁寝室用的那个才几十块,不知道靠不靠谱。” “有没有免费的降AI工具?” 每年毕业季,这些问题都会在各个论文交…...
无穷的奥秘 | 康托尔集合论与无穷算术
注:英文引文,机翻未校。 如有内容异常,请看原文。 Unraveling the Mysteries of Infinity 揭开无穷的奥秘 Jimmie Lawson 吉米劳森 Louisiana State University 路易斯安那州立大学 Infinity – p. 无穷 —— 第 页 Thinking about the …...
深入理解RAC中的gc buffer busy:从原理到避坑指南
深入解析RAC中的gc buffer busy:原理剖析与实战优化 在Oracle RAC环境中,gc buffer busy等待事件是影响性能的常见瓶颈之一。不同于单机数据库中的buffer busy waits,这一现象直接反映了集群环境下多实例间数据块协同访问的复杂性。本文将带您…...
ICASSP2023|达摩院语音实验室14篇论文技术亮点全解析
1. 达摩院语音实验室的ICASSP2023技术突破全景 每年ICASSP会议都是语音技术领域的风向标,今年达摩院语音实验室的14篇入选论文就像一套"技术组合拳",覆盖了从基础研究到产业落地的完整链条。我仔细研读了这些论文,发现它们有个共同…...
突破设备壁垒:用swyh-rs构建零成本家庭音频网络的新方案
突破设备壁垒:用swyh-rs构建零成本家庭音频网络的新方案 【免费下载链接】swyh-rs Stream What You Hear written in rust, inspired by SWYH. 项目地址: https://gitcode.com/gh_mirrors/sw/swyh-rs 在智能家居普及的今天,音频设备却常常陷入&qu…...
PyTorch 2.8镜像问题解决:常见CUDA内存不足、加载慢等故障排查指南
PyTorch 2.8镜像问题解决:常见CUDA内存不足、加载慢等故障排查指南 你是不是也遇到过这样的场景?在云端启动了一个全新的PyTorch 2.8镜像,准备大展身手训练模型,结果刚跑几行代码就弹出“CUDA out of memory”的红色警告。或者&a…...
别再死记硬背了!用Python的Scipy库5分钟搞定CDF计算与可视化
别再死记硬背了!用Python的Scipy库5分钟搞定CDF计算与可视化 每次看到统计学教材里那些复杂的概率公式,是不是觉得头大?作为数据分析新手,你可能更关心如何快速解决问题,而不是推导数学定理。今天我们就用Python的scip…...
数据协作新范式:提升团队效率的Teable平台技术指南
数据协作新范式:提升团队效率的Teable平台技术指南 【免费下载链接】teable 项目地址: https://gitcode.com/GitHub_Trending/te/teable 在当今数据驱动的工作环境中,团队常常面临数据孤岛、协作低效和流程僵化的挑战。市场部的销售数据散落在多…...
Swagger3.0高效实践:RuoYi-Vue接口文档自动生成指南
Swagger3.0高效实践:RuoYi-Vue接口文档自动生成指南 【免费下载链接】RuoYi-Vue :tada: (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本 …...
