设计模式8:代理模式-动态代理
上一篇:设计模式8:代理模式-静态代理
目录
- 如何理解“动态”这两个字?
- 动态代理简单的代码实例
- 一个InvocationHandler代理多个接口
- 有动态代理,为什么还要用Cglib代理?
如何理解“动态”这两个字?
“动态”的含义是代码生成代理类,一个代理类可以代理多个接口。
动态区别于死板,静态代理中一个代理类只能代理一个接口,其他不同的接口,就需要再手写不同的代理类,这就很死板。
动态代理类似于在安卓里面,我们常说的动态申请权限,其实就是用java或kotlin代码申请权限,而不是在AndroidManifest.xml文件里面写死,一次可以申请一个或多个权限。
上一篇:中,StationProxy和StarProxy都是我们手写的代理类。动态代理可以自动生成代理类。
动态代理简单的代码实例
动态代理需要jdk中提供的两个类InvocationHandler和Proxy,重写InvocationHandler接口实现代理方法,Proxy负责生成代理对象。
上篇文章中“明星代理”的例子,用动态代理实现如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;interface IStar {void sing(double money);
}class StarImpl implements IStar {public void sing(double money) {System.out.println("唱歌,收入" + money + "元");}
}class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("请先预约时间");System.out.println("沟通出场费用");double money= (double) args[0];if (money < 100000) {System.out.println("对不起,出场费10w万以内不受理");return null;}System.out.println("经纪人抽取了"+ money * 0.2 + "代理费用");args[0] = money * 0.8;Object result = method.invoke(target, args);System.out.println("演唱完毕");return result;}
}public class DynamicProxyExample {public static void main(String[] args) {//原始对象IStar mStar = new StarImpl();InvocationHandler handler = new MyInvocationHandler(mStar);//代理对象IStar proxyHello = (IStar) Proxy.newProxyInstance(mStar.getClass().getClassLoader(),mStar.getClass().getInterfaces(),handler);proxyHello.sing(200000);}
}
运行结果:
请先预约时间
沟通出场费用
经纪人抽取了40000.0代理费用
唱歌,收入160000.0元
演唱完毕
一个InvocationHandler代理多个接口
动态代理的核心优势就在于,一个代理类,可以代理多个接口。如下,演示的是一个代理handler,同时代理两个接口InterfaceA和InterfaceB:
package dynamic_proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;interface InterfaceA {void methodA();
}interface InterfaceB {void methodB();
}class ClassA implements InterfaceA {public void methodA() {System.out.println("执行methodA");}
}class ClassB implements InterfaceB {public void methodB() {System.out.println("执行methodB");}
}class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.getName().equals("methodA")) {System.out.println("调用methodA之前");Object result = method.invoke(target, args);System.out.println("调用methodA之后");return result;} else if (method.getName().equals("methodB")) {System.out.println("调用methodB之前");Object result = method.invoke(target, args);System.out.println("调用methodB之后");return result;} else {throw new UnsupportedOperationException("Unsupported method: " + method.getName());}}
}public class DynamicProxyExample {public static void main(String[] args) {InvocationHandler handlerA = new MyInvocationHandler(new ClassA());InterfaceA proxyA = (InterfaceA) Proxy.newProxyInstance(handlerA.getClass().getClassLoader(),new Class[]{InterfaceA.class},handlerA);proxyA.methodA();InvocationHandler handlerB = new MyInvocationHandler(new ClassB());InterfaceB proxyB = (InterfaceB) Proxy.newProxyInstance(handlerB.getClass().getClassLoader(),new Class[]{InterfaceB.class},handlerB);proxyB.methodB();}
}
代码执行结果:
调用methodA之前
执行methodA
调用methodA之后
调用methodB之前
执行methodB
调用methodB之后
动态代理大揭秘,带你彻底弄清楚动态代理!
有动态代理,为什么还要用Cglib代理?
动态代理只能把代理对象,赋值给接口,如上面的例子。不能把代理对象直接赋值一个普通类。而Cglib代理可以做到。具体怎么做的,下篇文章再讲。
相关文章:
设计模式8:代理模式-动态代理
上一篇:设计模式8:代理模式-静态代理 目录 如何理解“动态”这两个字?动态代理简单的代码实例一个InvocationHandler代理多个接口有动态代理,为什么还要用Cglib代理? 如何理解“动态”这两个字? “动态”…...
tcp字节传输(java)-自定义包头和数据识别
1、背景 tcp传输的时候会自动拆包,因此服务端接收的数据段可能跟客户端发送过来的数据段长度不一致,比如客户端一次发送10000个字节。但是服务端接收了两次才接收完整(例如第一次接收6000字节,第二次接收4000字节)。但…...
pyspark 系统找不到指定的路径; \Java\jdk1.8.0_172\bin\java
使用用具PyCharm 2023.2.1 1:pyspark 系统找不到指定的路径, Java not found and JAVA_HOME environment variable is not set. Install Java and set JAVA_HOME to point to the Java installation directory. 解决方法:配置正确环境变量…...
UE4 Physics Constraint Actor 实现钟摆效果
放入场景,然后将一个球体放入场景 选择小球 将小球改为Movable 选择模拟物理,并将小球移除平衡点 就实现了...
UE4/UE5 动画控制
工程下载 https://mbd.pub/o/bread/ZJ2cm5pu 蓝图控制sequence播放/倒播动画: 设置开启鼠标指针,开启鼠标事件 在场景中进行过场动画制作 设置控制事件...
Springboot整合shiro
导入依赖 <!-- 引入springboot的web项目的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> <!-- shiro --><depende…...
阻塞/非阻塞、同步/异步(网络IO)
1.阻塞/非阻塞、同步/异步(网络IO) 【思考】典型的一次 IO 的两个阶段是什么? 数据就绪 和 数据读写 数据就绪 :根据系统 IO 操作的就绪状态 阻塞 非阻塞 数据读写 :根据应用程序和内核的交互方式 同步 异步 陈硕:在处理 IO …...
为什么大家会觉得考PMP没用?
一是在于PMP这套知识体系,是一套底层的项目管理逻辑框架,整体是比较抽象的。大家在学习工作之后,会有人告诉你很多职场的一些做事的规则,比如说对于沟通,有人就会告诉如何跟客户沟通跟同事相处等等,这其实就…...
AVR128单片机 USART通信控制发光二极管显示
一、系统方案 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 void port_init(void) { PORTA 0xFF; DDRA 0x00;//输入 PORTB 0xFF;//低电平 DDRB 0x00;//输入 PORTC 0xFF;//低电平 DDRC 0xFF;//输出 PORTE 0xFF; DDRE 0xfE;//输出 PO…...
为什么5G 要分离 CU 和DU?(4G分离RRU 和BBU)
在 Blog 一文中,5G--BBU RRU 如何演化到 CU DU?_5g rru_qq_38480311的博客-CSDN博客 解释了4G的RRU BBU 以及 5G CU DU AAU,主要是讲了它们分别是什么。但是没有讲清楚 为什么,此篇主要回答why。 4G 为什么分离基站为 RRU 和 BBU…...
Python中的数据输入
获取键盘输入 input语句 使用input()可以从键盘获取输入,使用一个变量来接收 print("你是谁?") name input() print(f"我知道了,你是{name}")# print("你是谁?") name input("你是谁&…...
cms系统稳定性压力测试出现TPS抖动和毛刺的性能bug【杭州多测师_王sir】
一、并发线程数100,分10个阶梯,60秒加载时间,运行1小时进行压测,到10分钟就出现如下 二、通过jstat -gcutil 16689 1000进行监控...
【UE】材质描边、外发光、轮廓线
原教学视频链接: ue4 材质描边、外发光、轮廓线_哔哩哔哩_bilibili 步骤 1. 首先新建一个材质,这里命名为“Mat_outLine” 在此基础上创建一个材质实例 2. 在视口中添加一个后期处理体积 设置后期处理体积为无限范围 点击添加一个数组 选择“资产引用”…...
百模大战,打响AI应用生态的新赛点
点击关注 文|郝鑫 黄小艺,编|刘雨琦 “宇宙中心”五道口,又泛起了昔日的光芒。 十字路口一角的华清嘉园里,各种互联网大佬们,王兴、程一笑、张一鸣等人的创业传说似乎还有余音,后脚搬进来的AI…...
【C++二叉树】进阶OJ题
【C二叉树】进阶OJ题 目录 【C二叉树】进阶OJ题1.二叉树的层序遍历II示例代码解题思路 2.二叉搜索树与双向链表示例代码解题思路 3.从前序与中序遍历序列构造二叉树示例代码解题思路 4.从中序与后序遍历序列构造二叉树示例代码解题思路 5.二叉树的前序遍历(非递归迭…...
C++——vector:resize与reserve的区别,验证写入4GB大数据时相比原生操作的效率提升
resize和reserve的区别 reserve:预留空间,但不实例化元素对象。所以在没有添加新的对象之前,不能引用容器内的元素。而要通过调用push_back或者insert。 resize:改变容器元素的数量,且会实例化对象(指定或…...
基础配置xml
# 配置端口 server.port8081# 文件上传配置 # 是否支持文件上传 spring.servlet.multipart.enabledtrue # 是否支持文件写入磁盘 spring.servlet.multipart.file-size-threshold0 # 上传文件的临时目录 spring.servlet.multipart.locationd:/opt/tmp # 最大支持上传文件大小 sp…...
win环境安装SuperMap iserver和配置许可
SuperMap iServer是我国北京超图公司研发的基于跨平台GIS内核的云GIS应用服务器产品,通过服务的方式,面向网络客户端提供与专业GIS桌面产品相同功能的GIS服务,能够管理、发布多源服务,包括REST服务、OGC服务等。 SuperMap iserve…...
【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER(一)
文章目录 TASK系列解析文章前言PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER功能介绍PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER相关配置PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER流程确定优化变量定义目标函数定义约束ProcessSetUpStatesAndBoundsOptimizeByQPCheckSpeedLimitF…...
pytest parametrize多参数接口请求及展示中文响应数据
编写登陆接口 app.py from flask import Flask, request, jsonify, Responseapp Flask(__name__)app.route(/login, methods[POST]) def login():username request.form.get(username)password request.form.get(password)# 在这里编写你的登录验证逻辑if username admin…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
