3_代理模式(动态代理JDK原生和CGLib)
一.代理模式
1.概念
代理模式(Proxy Pattern )是指为其他对象提供一种代理,以控制对这个对象的访问,属于结构型模式。
在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。
2.代理模式三种角色
2.1 抽象角色( Subject ): 抽象主题类的主要职责是声明真实主题与代理的共同接口方法,该类可以是接口也可以是抽象类
2.2 真实角色(RealSubiect ): 该类也被称为被代理类,该类定义了代理所表示的真实对象,是负责执行系统真正的逻辑业务对象:
2.3 代理角色 ( Proxy): 也被称为代理类,其内部持有 RealSubiect 的用,因此具备完全的对RealSubiect 的代理权。客户端调用代理对象的方法,同时也调用被代理对象的方法,但是会在代理对象前后增加一些处理代码。
二.代理模式的通用写法
2.1 创建一个抽象角色:用于代理和真实对象共同接口方法。
public interface ISubject {void request();
}
2.2 创建一个真实角色:用于执行真正的业务逻辑处理。
public class RealSubject implements ISubject {public void request() {System.out.println("real service is called.");}
}
2.3 创建一个代理角色:调用真实业务逻辑时候前后自己处理逻辑代码。
public class Proxy implements ISubject {//1.获取真实对象封装处理private ISubject subject;public Proxy(ISubject subject){this.subject = subject;}//2.调用真实对象业务逻辑,前后加一些自己逻辑增强处理。public void request() {before();subject.request();after();}//3.前后增加逻辑处理public void before(){System.out.println("called before request().");}public void after(){System.out.println("called after request().");}
}
2.4 测试功能
public class Client {public static void main(String[] args) {//创建代理对象并绑定一个真实对象Proxy proxy = new Proxy(new RealSubject());//执行代理对象功能调用proxy.request();}
}//--结果处理------------
called before request().
real service is called.
called after request().
三.静态代理到动态代理
1.抽取角色:定义一个接口用于真实和代理对象共同的接口方法
//定义人的接口,相亲接口方法
public interface IPerson {void findLove();
}
2.真是角色:创建一个真正的人的对象并实现相亲接口方法具体逻辑
//定义一个张三人对象并提出相亲的要求
public class ZhangSan implements IPerson {public void findLove() {System.out.println("张三:要求相亲女孩长得好看又善良");}
}3.代理角色:创建一个代理张三对象(张三的父亲)代理完成张三的相亲要求。
public class ZhangLaosan implements IPerson {//---静态代理------------------------//1.创建获取静态代理对象处理【只能接受张三这个人,其他人不能接受】private ZhangSan zhangsan;public ZhangLaosan(ZhangSan zhangsan) {this.zhangsan = zhangsan;}//2.完成张三的相亲,并在相亲的前后做一些工作和处理。public void findLove() {System.out.println("张老三开始物色");zhangsan.findLove();System.out.println("开始交往");}//---动态代理------------------------//1.创建获取动态代理对象处理【只要实现抽象角色的接口,任何真实对象都可以接受并执行代理逻辑】private IPerson person;public ZhangLaosan(IPerson person) {this.person = person;}//2.完成张三的相亲,并在相亲的前后做一些工作和处理。public void findLove() {System.out.println("张老三开始物色");person.findLove();System.out.println("开始交往");}
}4.测试代码
public class Test {public static void main(String[] args) {ZhangLaosan zhangLaosan = new ZhangLaosan(new ZhangSan());zhangLaosan.findLove();}
}结果:张老三开始物色张三:要求相亲女孩长得好看又善良开始交往
四. JDKProxy动态代理
1.抽取角色:定义一个接口用于真实和代理对象共同的接口方法
public interface IPerson {void findLove();
}2.真是角色:创建一个真正的人的对象并实现相亲接口方法具体逻辑
//定义一个张三人对象并提出相亲的要求
public class ZhangSan implements IPerson {public void findLove() {System.out.println("张三:要求相亲女孩长得好看又善良");}
}3.代理角色:创建一个代理张三对象(张三的父亲)代理完成张三的相亲要求。
public class JdkMeipo implements InvocationHandler {//1.定义接受真实对象变量private IPerson target;public IPerson getInstance(IPerson target){this.target = target; //真实对象赋值//clazz.getClassLoader():真实对象反射类对象(可以通过目标类的getClassLoader()方法来获取目标类的ClassLoader对象)//clazz.getInterfaces():真实对象接口列表 (Class[]对象,代理类要实现的接口列表。代理类将会实现这些接口,并且可以调用接口中定义的方法)//this:真实对象(InvocationHandler接口的实现类对象,代理类在调用方法时会委托给该InvocationHandler对象来处理)Class<?> clazz = target.getClass();return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {before();Object result = method.invoke(this.target,args);after();return result;}private void after() {System.out.println("双方同意,开始交往");}private void before() {System.out.println("我是媒婆,已经收集到你的需求,开始物色");}
}4.测试
public class Test {public static void main(String[] args) {JdkMeipo jdkMeipo = new JdkMeipo();//创建一个代理对象IPerson zhangsan = jdkMeipo.getInstance(new Zhangsan());//把真实对象代理处理一个代理张三的对象zhangsan.findLove();}
}结果:张老三开始物色张三:要求相亲女孩长得好看又善良开始交往
五. CGlib动态代理
依赖maven cglib库
cglib
cglib-nodep
2.2
1.定义真实对象类并写真实的业务逻辑处理。
public class Customer {public void findLove(){System.out.println("儿子要求:肤白貌美大长腿");}
}2.定义代理对象
public class CGlibMeipo implements MethodInterceptor {//1.定义接受真实对象处理,返回一个代理对象public Object getInstance(Class<?> clazz) throws Exception{//相当于Proxy,代理的工具类Enhancer enhancer = new Enhancer();enhancer.setSuperclass(clazz);enhancer.setCallback(this);return enhancer.create();}/*o:被代理的对象。即原始对象,也就是目标类的实例。method:要被调用的方法对象。即将要执行的目标方法。objects:方法的参数数组。即目标方法的参数列表。methodProxy:方法的代理对象。通过该对象可以调用目标方法。使用methodProxy.invokeSuper(o, objects)可以触发目标方法的执行。*/public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {before();Object obj = methodProxy.invokeSuper(o,objects);after();return obj;}private void before(){System.out.println("我是媒婆,我要给你找对象,现在已经确认你的需求");System.out.println("开始物色");}private void after(){System.out.println("OK的话,准备办事");}
}3.测试
public class CglibTest {public static void main(String[] args) {try {System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"E://cglib_proxy_classes");//打印代理对象生成的class文件//CGlibMeipo代理对象绑定真实对象并返回代理对象Customer obj = (Customer) new CGlibMeipo().getInstance(Customer.class);//执行代理对象方法并调用真实对象obj.findLove();} catch (Exception e) {e.printStackTrace();}}
}
六. 代理模式的优缺点
代理模式具有以下优点
(1)代理模式能将代理对象与真实被调用目标对象分离
(2)在一定程度上降低了系统的耦合性,扩展性好
(3)可以起到保护目标对象的作用
(4)可以增强目标对象的功能
当然,代理模式也有缺点
( 1)代理模式会造成系统设计中类的数量增加
(2)在客户端和目标对象中增加一个代理对象,会导致请求处理速度变慢.
(3)增加了系统的复杂度
七. JDK Proxy和CGLib比较
JDK是采用读取接口的信息
CGLib覆盖父类方法
目的:都是生成一个新的类,去实现增强代码逻辑的功能
JDK Proxy 对于用户而言,必须要有一个接口实现,目标类相对来说复杂
CGLib 可以代理任意一个普通的类,没有任何要求
CGLib 生成代理逻辑更复杂,效率,调用效率更高,生成一个包含了所有的逻辑的FastClass,不再需要反射调用
JDK Proxy生成代理的逻辑简单,执行效率相对要低,每次都要反射动态调用
CGLib 有个坑,CGLib不能代理final的方法
相关文章:
3_代理模式(动态代理JDK原生和CGLib)
一.代理模式 1.概念 代理模式(Proxy Pattern )是指为其他对象提供一种代理,以控制对这个对象的访问,属于结构型模式。 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的…...
Linux的权限(1)
目录 操作系统的"外壳"程序 外壳程序是什么? 为什么存在外壳程序? 外壳程序怎么运行操作? 权限 什么是权限? 权限的本质? Linux中的(人)用户权限? su和su -的区别…...
数据安全保障的具体措施有哪些
随着信息化时代的到来,数据已经成为企业和社会发展的重要资产。然而,数据安全问题也日益突出,如何保障数据的安全性、完整性和可用性成为了亟待解决的问题。以下将详细探讨数据安全保障的各个方面,以期为企业和社会提供更好的数据…...
浅谈标签及应用场景
一、标签的定义 标签是根据业务场景的需求,通过对目标对象(包含静态、动态特性),运用抽象、归纳、推理等算法得到的高度精炼的特征标识,用于差异化管理与决策。标签由标签名称和标签值组成,打在目标对象上…...
Linux动态分配IP与正向解析DNS
目录 一、DHCP分配 1. 动态分配 1.1 服务端服务安装 1.2 修改服务端dhcp配置 1.3 修改客户端dhcp,重启查询网卡信息 2. 根据mac固定分配 2.1 修改服务器端dhcp服务配置 2.2 客户端自动获取,查看网卡信息 二、时间同步 1. 手动同步 2. 自动同…...
pyspark 使用udf 进行预测,发现只起了一个计算节点
PySpark UDF 只使用一个计算节点的问题 原因分析 默认的并行度设置 PySpark在执行UDF(用户定义函数)时,默认可能不会利用所有可用的计算节点。这是因为UDF通常在单个节点上执行,并且如果没有正确设置分区,可能会导致数…...
mysql触发器的简单使用
mysql触发器 触发器是一个特殊的存储过程,在事件delete、insert、update发生时自动执行一条或多条SQL语句(执行多条SQL语句需要用begin、end 包裹起来) 创建触发器 创建触发器的四大必要条件 唯一的触发器名称触发器关联的表触发器响应的…...
全志T113开发板Qt远程调试
1引言 通常情况下工程师在调试Qt程序时,需要频繁制作镜像烧录到核心板来测试Qt程序是否完善,这样的操作既费时又费力。这时我们可以通过QtCreator设备功能,定义设备后,在x86_64虚拟机上交叉编译qt程序,将程序远程部署到…...
学习使用php、js脚本关闭当前页面窗口的方法
学习使用php、js脚本关闭当前页面窗口的方法 前言方法一:使用JavaScript代码方法二:通过http头文件来实现方法三:使用服务器端脚本来实现 前言 在开发web应用程序时,我们通常需要在不同的网页之间进行导航。通常情况下࿰…...
python 人脸检测与人脸识别
安装库文件: pip install dlib face_recognition import dlib import face_recognition import cv2 from PIL import Image, ImageDraw# 判断运行环境 cpu or gpu def check_env():print(dlib.DLIB_USE_CUDA)print(dlib.cuda.get_num_devices())# 判断人脸在图片当中的位置 def…...
RT-Thread: ulog 日志 讲解和使用
说明:记录 RT-Thread: ulog 日志功能和使用流程。 官网资料链接: https://docs.rt-thread.org/#/rt-thread-version/rt-thread-standard/programming-manual/ulog/ulog 1.ulog 简介 日志的定义:日志是将软件运行的状态、过程等信息&#x…...
git ssh key 配置
一、Profile Settings-->SSH Keys 我们点击这里会有详情的文档介绍生成sshkey。 ssh-keygen -t rsa -b 2048 -C "邮箱" --回车... 将生成的id_rsa.pub粘贴到如下保存 git config --global user.name "用户名" git config --global user.email "邮…...
MongoDB聚合:$documents
$documents阶段可以根据输入值返回字面意义的文档。 语法 { $documents: <表达式> }$documents接受可解析为对象数组的任何有效表达式,包括: 系统变量,如 $$NOW 或 $$SEARCH_META $let 表达式 $lookup 表达式作用域中的变量 没有…...
程序员英语 - 英文会议常用句型
相信大部分程序员都会有如下经历: 产品经理(BA)们在和外系统聊集成方案时或者给用户解决某个问题时发现搞不定了,这个时候就会拉上程序员一起上会参与讨论或者排查问题,但程序员们英文又不好,上了会又听不懂…...
UV贴图和展开初学者指南
在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 介绍 这正是本文的主题——UV贴图——登上舞台的时候。大多数 3D 建…...
解密Path环境变量
解密Path环境变量 大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,让我们一起深入探讨程序开发中不可或缺的一项关键技术——“path环境变量”。无论…...
git撤销提交到本地的commit
有些时候,当我们提交代码到本地后,突然发现因为某些原因需要撤销提交本地的代码。 就比如我,因为代码写错了分支,已经提交到本地了,而我需要取消,并且还要把代码搞得另外的分支上。 提交前: …...
使用Adobe Acrobat Pro DC给pdf文件填加水印
前言 GPT4的官方售价是每月20美元,很多人并不是天天用GPT,只是偶尔用一下。 如果调用官方的GPT4接口,就可以按使用量付费,用多少付多少,而且没有3个小时内只能提问50条的使用限制。 但是对很多人来说调用接口是比较麻烦…...
解决:Unity : Error while downloading Asset Bundle: Couldn‘t move cache data 问题
目录 问题: 尝试 问题得到解决 我的解释 问题: 最近游戏要上线,发现一个现象,部分机型在启动的时候闪退或者黑屏,概率是5%左右,通过Bugly只有个别机型才有这个现象,其实真实情况比这严重的多…...
SpringBoot默认配置文件
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容:SpringBoot默认配置文件 📚个人知识库: Leo知识库,欢迎大家访问 1.前言☕…...
【Typst源文件】Typst 纸张定义完全指南
Typst 通过 page 函数来定义纸张的尺寸、边距、方向等属性。通常使用 #set page() 规则在文档开头进行全局设置。 1. 基础纸张设置 1.1 使用标准纸张尺寸 Typst 支持丰富的标准纸张尺寸,只需传入纸张名称字符串即可: // 设置为 A4 纸张(默…...
如何高效使用猫抓cat-catch:5个关键技巧完全指南
如何高效使用猫抓cat-catch:5个关键技巧完全指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是否经常遇到这样的情况:…...
智能电动汽车芯片全景解析:从MCU到SoC的技术跃迁
1. 智能电动汽车的芯片革命:从机械控制到数字大脑 十年前打开汽车引擎盖,看到的是一堆机械部件和少量电子控制单元;现在掀开一辆特斯拉的"前备箱",映入眼帘的却是布满芯片的电路板。这个直观变化背后,是汽车…...
Syncthing中继服务器搭建全攻略:解决公共服务器速度慢的问题(附详细配置步骤)
Syncthing中继服务器搭建实战:突破公共服务器速度瓶颈 周末团队协作时,Syncthing公共中继服务器的龟速让人抓狂——跨国传输一个设计稿居然要两小时。这促使我探索自建中继服务器的方案,实测将同步速度提升8倍。本文将分享从服务器选型到客户…...
如何通过Cowabunga Lite实现iOS安全定制与个性体验
如何通过Cowabunga Lite实现iOS安全定制与个性体验 【免费下载链接】CowabungaLite iOS 15 Customization Toolbox 项目地址: https://gitcode.com/gh_mirrors/co/CowabungaLite 1. 三分钟完成首次配置:从连接到应用的极简流程 当你第一次打开Cowabunga Lit…...
从HBM到IEC61000-4-2:解码三大ESD模型在芯片与整机设计中的关键分野
1. 为什么你的芯片还是被静电打坏了? 很多硬件工程师都有过这样的困惑:明明选用的芯片数据手册上明确标注了"ESD防护等级2000V",为什么产品到客户手里还是频繁出现静电损坏?上周我就遇到一个真实案例——某智能门锁厂商…...
Qwen3.5-9B-AWQ-4bit实战教程:用‘概括最重要信息’提示词压缩冗余输出
Qwen3.5-9B-AWQ-4bit实战教程:用"概括最重要信息"提示词压缩冗余输出 1. 认识Qwen3.5-9B-AWQ-4bit模型 Qwen3.5-9B-AWQ-4bit是一个强大的多模态AI模型,它能同时理解图片和文字。想象一下,你给这个AI看一张照片,然后问…...
用YOLOv8在树莓派上跑个‘狗脸识别’:斯坦福犬类数据集实战与轻量化部署指南
树莓派上的智能犬种识别:YOLOv8轻量化部署全流程实战 当你在公园遛狗时,有没有遇到过路人好奇询问狗狗品种的情况?传统的犬种识别往往依赖专业兽医或资深养犬人士的经验判断,而今天我们将用一块信用卡大小的树莓派,配合…...
基于Pixel Epic · Wisdom Terminal的MySQL智能运维:安装配置与性能调优
基于Pixel Epic Wisdom Terminal的MySQL智能运维:安装配置与性能调优 1. 引言 MySQL作为最流行的开源关系型数据库,在各类业务系统中扮演着核心角色。但传统的数据库运维往往面临几个痛点:配置参数复杂难懂、SQL优化依赖经验、性能问题排查…...
抖音内容采集工具的技术创新与合规应用实践
抖音内容采集工具的技术创新与合规应用实践 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖音批量下载工具&…...
