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…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...
