当前位置: 首页 > news >正文

JDK动态代理和CGLIB动态代理案例分析

 JDK动态代理和CGLIB动态代理案例分析

JDK动态代理和CGLIB动态代理的实现原理如下:

  1. JDK动态代理的实现原理:

    • JDK动态代理是基于Java的反射机制实现的
    • 实现一个继承InvocationHandler接口的对象,重写invoke方法,invoke方法中可以在目标方法执行前后添加一些额外的逻辑,该对象负责处理代理对象的方法调用。
    • 当使用JDK动态代理时,通过Proxy类的newProxyInstance方法创建代理对象,需要传入三个参数,分别是目标对象的类加载器、接口列表和一个实现了`InvocationHandler`接口的对象。
    • 在代理对象的方法被调用时,InvocationHandlerinvoke方法会被触发,通过反射机制调用目标对象的方法。
  2. 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动态代理的实现原理如下&#xff1a; JDK动态代理的实现原理&#xff1a; JDK动态代理是基于Java的反射机制实现的实现一个继承InvocationHandler接口的对象&#xff0c;重写invoke方法&#xff0c;invoke方法中可以在目…...

【数据结构-前缀哈希】力扣1124. 表现良好的最长时间段

给你一份工作时间表 hours&#xff0c;上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候&#xff0c;那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」&#xff0c;意味在这段时间内&#xff0c;「劳累的天数」是严格 大…...

电商平台产品ID|CDN与预渲染|前端边缘计算

技术实现 都是通过ID拿到属性&#xff0c;进行预渲染html&#xff0c;通过 oss 分发出去 详情页这种基本都是通过 ssr 渲染出来&#xff0c;然后上缓存 CDN 分发到边缘节点来处理&#xff0c;具体逻辑可以参考 淘宝——EdgeRoutine边缘计算&#xff08;CDNServerless 边缘计算…...

LATTICE进阶篇DDR2--(4)DDR2 IP核总结

一、IP核的时钟框架 1片DDR2的接口是16位&#xff0c;且DDR2是双边沿读取的&#xff0c; 故当DDR2芯片的时钟为200M时&#xff0c;右侧DDR2芯片上的数据吞吐率为200M*2*16b&#xff0c;左侧数据吞吐率为200M*32b&#xff0c;左右两侧数据吞吐量相等。 根据上规律可知&#xf…...

windows下php安装kafka

下载zookeeper Kafka 依赖 Zookeeper 进行分布式协调&#xff0c;所以需要下载Zookeeper &#xff0c;当然你也可以使用kafka包里自带的一个默认配置的 Zookeeper。这里我们单独下载一个 访问Zookeeper官方下载页面在页面中找到最新的稳定版本&#xff0c;点击相应的下载链接…...

【wiki知识库】09.欢迎页面展示(浏览量统计)SpringBoot部分

&#x1f34a; 编程有易不绕弯&#xff0c;成长之路不孤单&#xff01; 大家好&#xff0c;我是熊哈哈&#xff0c;这个项目从我接手到现在有了两个多月的时间了吧&#xff0c;其实本来我在七月初就做完的吧&#xff0c;但是六月份的时候生病了&#xff0c;在家里休息了一个月的…...

数据分析与应用:微信-情人节红包流向探索分析

目录 0 需求描述 1 红包发送方用户的基本信息缺失率有多高?(即有多少红包发送方用户无法在用户基本信息表中匹配? 2 哪一组红包金额的拒收率最高? 3、最受二线城市欢迎的红包金额为?(即发出次数最多) 4 北上广深 4 大城市中,哪座城市的男性用户发出的 520 红包比例…...

SQL,获取 ID 的历史状态

sas系统的表tb存储病人的医疗历史记录&#xff0c;当Visit_codeSurgery时表示手术&#xff0c;Visit_codeOffice表示咨询&#xff0c;每个病人有多条Visit_code&#xff0c;有时只有Surgery或只有Office&#xff1a;IdVisit_DateVisit_codeA305/15/2004SurgeryA302/5/2005Offic…...

阅文集团:摇不动的IP摇钱树

把IP当成摇钱树&#xff0c;要做“东方迪士尼” 今天我们聊——阅文集团 《热辣滚烫》《庆余年2》《与凤行》和《玫瑰的故事》很熟悉吧&#xff1f;影视“四连爆”&#xff0c; 阅文集团交出一份亮眼半年报&#xff0c;时隔两年&#xff0c;重启增长。 跟IP相关业务对收入贡献…...

ETL数据集成丨将SQL Server数据同步至Oracle的具体实现

一、背景 在构建企业级数据架构时&#xff0c;将SQL Server数据库的数据同步至数仓数据库&#xff08;如Oracle&#xff09;是一项至关重要的任务。这一过程不仅促进了跨系统数据的一致性与可用性&#xff0c;还为数据分析、商业智能以及决策支持系统提供了坚实的数据基础。 …...

20240814软考架构-------软考51-55答案解析

每日打卡题51-55答案 51、【2017年真题】 难度&#xff1a;一般 系统移植也是系统构建的一种实现方法&#xff0c;在移植工作中&#xff0c; 需要最终确定移植方法。 A.计划阶段 B.准备阶段 C.转换阶段 D.验证阶段 答案&#xff1a;A 解析&#xff1a; 移植工作大体上分为计划…...

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 等 根据需要&#xff0c;要实现一个下载文档的需要 最简单的方法就是使用a标签 如果是相同域可以直接下载&#xff0c;但如果是不同域的&#xff0c;就会先打开一个预览页&#xff0c;在预览页再点下载…...

Java 空值与null 形参与实参学习

Java系列文章目录 文章目录 Java系列文章目录一、前言二、学习内容&#xff1a;三、问题描述四、解决方案&#xff1a;4.1 空值与null的区别4.1.1 空值&#xff08;Empty Value&#xff09;4.1.2 Null 4.2 形参与实参区别 五、总结&#xff1a;5.1 学习总结&#xff1a; 一、前…...

【QT常用技术讲解】QTableView添加QCheckBox、QPushButton

前言 QT展示列表信息的时候通常用到列表&#xff08;比如用户信息、机构信息、设备信息等菜单&#xff09;&#xff0c;当需要对某列进行修改、删除操作时&#xff0c;就需要加入按钮&#xff08;QPushButton&#xff09;&#xff0c;当需要对多列进行右键菜单操作时&#xff0…...

linux监控命令

在 Linux 中&#xff0c;有许多命令可以用于监控系统的性能和状态。以下是一些常用的监控命令及其用途&#xff1a; 1. top​ 和 htop​ top ​top​ 命令显示当前系统中运行的进程列表及其资源使用情况。 top​​ ‍ htop ​htop​ 是 top​ 命令的增强版&#xff0c;提…...

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实现地图省市区三级下钻

采用在线地图数据&#xff0c;整体简约&#xff0c;扩展也方便 参考 <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…...

从零构建开源语音AI交互中枢:EchoKit Server部署与调优指南

1. 项目概述&#xff1a;构建你自己的语音AI交互中枢 如果你对智能音箱、语音助手这类设备感兴趣&#xff0c;但又觉得市面上的产品要么功能封闭&#xff0c;要么隐私堪忧&#xff0c;那么今天聊的这个项目——EchoKit Server&#xff0c;可能会让你眼前一亮。简单来说&#x…...

Smart_rtmpd配置全解:从单局域网到跨网段,你的OBS推流服务器搭建指南

Smart_rtmpd高阶配置指南&#xff1a;从局域网到跨网段的OBS推流实战 在当前的数字内容创作浪潮中&#xff0c;实时视频流传输已成为游戏直播、在线教育、企业内训等场景的刚需。对于技术爱好者和小型团队而言&#xff0c;自建推流服务器不仅能避免第三方平台的限制&#xff0c…...

Substance Painter入门:从模型到贴图的核心工作流解析

1. Substance Painter入门指南&#xff1a;从零开始掌握PBR材质创作 第一次打开Substance Painter时&#xff0c;很多人都会被它复杂的界面吓到。作为一个从Maya转战材质制作的老鸟&#xff0c;我完全理解这种感受。但别担心&#xff0c;只要掌握几个核心概念&#xff0c;你就…...

Codex:不只是程序员的代码助手,更是办公人士的高效伙伴

Codex&#xff1a;不只是程序员的代码助手&#xff0c;更是办公人士的高效伙伴 面向团队协作、文档处理、数据分析和日常执行的智能工作台 当人们谈到 Codex&#xff0c;第一反应往往是“写代码”。这当然是它的强项&#xff0c;但如果只把 Codex 看成程序员的专属工具&#…...

别再只会拖模块了!手把手教你用Simulink封装打造自己的‘智能积木’

从零构建你的Simulink智能积木库&#xff1a;封装技术实战指南 在工程建模领域&#xff0c;Simulink就像数字世界的乐高积木箱&#xff0c;但大多数用户只停留在拖拽现成模块的初级阶段。真正的高手都掌握了一项核心技能——模块封装。这就像把一堆散乱的乐高零件组装成功能完整…...

ADB 配置 + 入门使用全攻略,零基础看完就精通

一、ADB简介 1、什么是adb ADB 全称为 Android Debug Bridge&#xff0c;起到调试桥的作用&#xff0c;是一个客户端-服务器端程序。其中客户端是用来操作的电脑&#xff0c;服务端是 Android 设备。 ADB 也是 Android SDK 中的一个工具&#xff0c;可以直接操作管理 Androi…...

智能体可观测性实践:元观察技能的设计、集成与效能优化

1. 项目概述&#xff1a;一个面向智能体的“元观察者”技能最近在折腾智能体&#xff08;Agent&#xff09;开发的朋友&#xff0c;可能都遇到过类似的问题&#xff1a;你精心设计了一个智能体&#xff0c;给它配备了各种工具和技能&#xff0c;希望它能自主、流畅地完成一系列…...

别再瞎写 Prompt 了:2026年最实用的10条LLM提示词技巧

别再瞎写 Prompt 了&#xff1a;2026年最实用的10条LLM提示词技巧强烈推荐收藏&#xff01;从 OpenAI 官方指南到社区实践精华&#xff0c;每条技巧都附带 ❌ 错误示范 → ✅ 正确示范 → &#x1f4a1; 原理说明。这个问题你肯定遇到过 你打开 ChatGPT&#xff0c;输入&#x…...

CM-GAI:融合最优传输与连续介质力学的物理约束生成模型

1. 项目概述&#xff1a;当连续介质力学遇见最优传输在工程与材料科学的深水区&#xff0c;我们常常面临一个令人头疼的“数据荒”问题&#xff1a;极端条件下的物理场数据&#xff0c;比如材料在接近熔点的应力-应变行为&#xff0c;或者结构在超高冲击速度下的瞬态变形&#…...

别再死记硬背截止、放大、饱和了!用Arduino+面包板,5分钟直观演示三极管三种工作状态

用Arduino实战破解三极管工作状态的秘密 记得第一次学三极管时&#xff0c;盯着课本上那些截止区、放大区、饱和区的曲线图&#xff0c;我完全无法理解这些抽象概念和实际电路有什么关系。直到有一天&#xff0c;我在实验室里用Arduino和几个简单元件搭建了一个测试电路&#x…...