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

设计模式-代理模式(Java)

本篇文章详细说明代理模式并用代码简单介绍代理模式的用法,以及代理模式在实际应用中的源码简单解析。

1、什么是代理模式和代码实现

代理模式是一种设计模式,它允许在不改变原有类的情况下,为其提供一种代理机制,用于控制其访问权限、加强其功能等。

在Java中,代理模式通常使用接口进行实现。首先,我们定义一个接口,它是原有类和代理类的共同接口,以便于代理类能够代理原有类的所有功能。接着,我们实现原有类,并在代理类中持有原有类的引用,以便于代理类能够访问原有类的所有方法和属性。最后,我们实现代理类,并在其中对原有类的方法进行控制、加强等操作。

下面,我们通过一个简单的示例来介绍代理模式的实现。

首先,我们定义一个接口Subject,它是原有类RealSubject和代理类Proxy的共同接口,以便于代理类能够代理原有类的所有功能。代码如下:

public interface Subject {void request();
}

接着,我们实现原有类RealSubject,代码如下:

public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: handling request.");}
}

在代理类Proxy中,我们持有原有类RealSubject的引用,并在其request方法中对原有类的方法进行控制、加强等操作。代码如下:

public class Proxy implements Subject {private RealSubject realSubject;public Proxy() {this.realSubject = new RealSubject();}@Overridepublic void request() {System.out.println("Proxy: before handling request.");realSubject.request();System.out.println("Proxy: after handling request.");}
}

最后,我们可以使用代理类Proxy来代理原有类RealSubject的功能,代码如下:

public class Test{public static void main(String[] args) {Subject subject = new Proxy();subject.request();}
}

以上代码的输出结果为:

Proxy: before handling request.
RealSubject: handling request. 
Proxy: after handling request.

可以看出,在代理类Proxy中,我们成功地控制了原有类RealSubject的方法,实现了对其功能的加强。

在实际应用中,代理模式通常用于控制对某个对象的访问,例如对文件的访问权限、对网络资源的访问权限等。同时,代理模式还可以用于实现远程调用、懒加载等功能。

2、代理模式实际应用

Retrofit源码中使用了代理模式来实现对API接口的访问,具体的实现在Retrofit的create方法中。

在Retrofit中,我们首先通过Retrofit.Builder来创建一个Retrofit实例,并通过该实例的create方法来创建一个代理类。在create方法中,Retrofit会根据传入的API接口类,生成一个动态代理类,并在代理类中实现对API接口的访问。

下面,我们来看一下Retrofit中create方法的源码实现:

public <T> T create(final Class<T> service) {// 省略部分代码...// 创建动态代理类return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },new InvocationHandler() {private final Platform platform = Platform.get();private final Object[] emptyArgs = new Object[0];@Override public @Nullable Object invoke(Object proxy, Method method,@Nullable Object[] args) throws Throwable {// 省略部分代码...// 创建Call对象Call<?> call = serviceMethod.toCall(args);// 省略部分代码...// 发送请求并返回响应return callAdapter.adapt(call);}});
}

可以看出,create方法中的Proxy.newProxyInstance方法会根据传入的API接口类和InvocationHandler来生成一个动态代理类。在该动态代理类中,InvocationHandler会实现对API接口方法的访问。

在InvocationHandler的invoke方法中,首先通过serviceMethod.toCall(args)方法创建一个Call对象,该Call对象表示一个网络请求。然后,通过callAdapter.adapt(call)方法将Call对象转换为一个响应对象,并返回给调用者。

通过以上代码,我们可以看出Retrofit是如何使用代理模式来实现对API接口的访问的。通过动态代理类和InvocationHandler,Retrofit能够实现对API接口方法的访问,并将其转换为网络请求和响应。

3、总结

总之,代理模式是一种非常有用的设计模式,在Java中也有广泛的应用。我们可以通过定义接口、实现原有类和代理类等步骤,来实现对原有类的控制、加强等操作,从而实现更为灵活、安全和高效的应用。

相关文章:

设计模式-代理模式(Java)

本篇文章详细说明代理模式并用代码简单介绍代理模式的用法&#xff0c;以及代理模式在实际应用中的源码简单解析。 1、什么是代理模式和代码实现 代理模式是一种设计模式&#xff0c;它允许在不改变原有类的情况下&#xff0c;为其提供一种代理机制&#xff0c;用于控制其访问…...

如何处理负面评论?利用负面评论发挥优势

每家公司都应该做的一件事&#xff1a;回复评论&#xff01; 37%的买家积极考虑对评论的回应&#xff0c;以评估和对品牌的看法。所以不要忘记回复评论&#xff01; 如何处理负面评论 如果您的公司正在经历大量负面评论&#xff0c;请了解您的产品团队如何利用它们来发挥自己的…...

一个JAVA程序员必备的技能有哪些?知道这些帮你快速升职加薪

和其他行业一样&#xff0c;软件研发行业也有必须要掌握的工具&#xff0c;每个程序员只有学习了这些工具之后才会不断成长&#xff0c;今天就和大家分享一些程序员必备的十项技能。老实说&#xff0c;如果每个程序员都非常了解这些工具&#xff0c;那么他可以在日常工作中完成…...

DHTMLX Suite 8.0 重大发布,新增更多新主题、热图图表、辅助功能支持功能

DHTMLX Suite 是一个用于构建跨浏览器Web应用和移动应用的强大JavaScript UI库。DHTMLX UI 组件库允许您更快地构建跨平台、跨浏览器 Web 和移动应用程序。它包括一组丰富的即用式 HTML5 组件&#xff0c;这些组件可以轻松组合到单个应用程序界面中。 DHTMLX Spreadsheet正版试…...

[华为OD机试 ] Linux发行版的数量(C++ Java JS Python)

文章目录 题目描述输入描述输出描述备注用例题目解析C++JavaScriptJavaPython题目描述 Linux操作系统有多个发行版,distrowatch.com提供了各个发行版的资料。这些发行版互相存在关联,例如Ubuntu基于Debian开发,而Mint又基于Ubuntu开发,那么我们认为Mint同Debian也存在关联…...

HydroD 实用教程(五)Morsion Model

目 录一、前言二、Morison 方程三、Morison 单元与属性3.1 Anchor Elements3.2 Pressure Area Elements3.3 TLP Elements3.4 Morison 3D Elements3.5 Morison (2D) Sections四、Element Correspondence五、参考文献一、前言 SESAM &#xff08;Super Element Structure Analysi…...

成功解决xshell7会话窗口只能显示一个的问题

文章目录前言一. 问题复现二. 问题解决方法一方法二三. 拓展3.1 自定义快捷键3.2 将当前shell中的代码内容复制到记事本中3.3 xshell配置密钥登录3.3.1 生成密钥3.3.2 将密钥上传到服务器并设置3.3.3 用xshell密钥登录服务器总结前言 重点强调&#xff1a; 本文是解决xshell的…...

Spring security 个人理解

改文章写的很好&#xff1a;https://zhuanlan.zhihu.com/p/342755411 Spring security 分为两个部分 登陆认证权限认证 登陆认证 其实就是就是登陆注册&#xff0c;然后获取登陆凭证的问题 操作如下 登陆账号密码&#xff0c;通过账号查询出用户数据&#xff0c;然后密码进…...

线性表 顺序表数组

初识线性表 文章目录初识线性表线性表的类型定义基本操作&#xff08;一&#xff09;init&#xff0c;destory&#xff0c;clear基本操作&#xff08;二&#xff09; 判空 &#xff0c;求长基本操作&#xff08;三&#xff09;取值&#xff0c;取位置基本操作&#xff08;四&am…...

从WebRtc学习RTP协议

1、TCP为何不适用于实时音视频可靠性是以牺牲实时性为代价的。按照TCP原理&#xff0c;当出现极端网络情况时&#xff0c;理论上每个包的时延可达到秒级以上&#xff0c;而且这种时延是不断叠加的。这对于音视频实时通信来说是不可接受的。TCP为了实现数据传输的可靠性&#xf…...

centos7 配置samba

samba概述&#xff1a; Windows与Linux之间通信的桥梁&#xff0c;Samba是一个非常强大的文件服务器。Samba端口&#xff1a;udp 137 udp138&#xff0c;tcp139 tcp445。Samba工作模式&#xff1a;C/S模式&#xff08;客户端-服务器&#xff09; samba应用环境 1、文件共享&…...

前端转golang从小白到实战自学笔记(2023/3/1)

了解&#xff1a;https://www.runoob.com/go/go-concurrent.htmlgolang学习方向区块链研发工程师go服务器>&#xff08;特点&#xff1a;数据处理&#xff0c;处理大并发&#xff09;/游戏软件工程师golang分布式/云计算软件工程师&#xff08;盛大云、cdn、京东&#xff09…...

10个必须知道的JavaScript技巧,让你成为更好的程序员

1.Promise回调地狱Promises 提供了一种优雅的方式来处理 JavaScript 中的异步操作。这也是避免“回调地狱”的解决方案之一。但是我并没有真正理解它的意思&#xff0c;所以我写了这段代码。我做了这些事情&#xff1a;先获取用户的基本信息。按用户信息获取所有文章的简要摘要…...

蓝桥杯真题(JAVA)--分巧克力

题目描述儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。小明一共有 NN 块巧克力&#xff0c;其中第 i块是HiWi 的方格组成的长方形。为了公平起见&#xff0c;小明需要从这 NN 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足&…...

机器学习:学习KMeans算法,了解模型创建、使用模型及模型评价

机器学习&#xff1a;学习KMeans算法&#xff0c;了解模型创建、使用模型及模型评价 作者&#xff1a;AOAIYI 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;AOAIYI首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#…...

ChatGPT引爆AIGC,垂类龙头迎来“创新春天”

文|智能相对论作者|陈壹一款AI产品&#xff0c;到底有多神&#xff1f;ChatGPT刷新了我们的认知。它用2个月时间&#xff0c;完成TikTok花9个月&#xff0c;Instagram花2年半才做到的事&#xff0c;成为史上用户增速最快破亿的消费级应用程序。它也凭借一己之力&#xff0c;让谷…...

科技制造商必须对安全、设计选择承担更多责任

网络安全和基础设施安全局局长称当今商业网络安全的现状是"不可持续的"&#xff0c;公司、消费者和政府必须集体转变期望&#xff0c;让主要软件和硬件制造商对不安全的产品负责&#xff0c;而不是用户。 拜登政府预计将在未来几天发布一项战略&#xff0c;该战略将…...

HTML认知

HTML认知 文章目录HTML认知语法规范注释标签组成和关系标签的关系标签学习排版系列标签**标题标签****段落标签**换行标签水平线标签文本格式化标签媒体标签图片标签src 目标图片的路径alt 替换文本title 图片的标题width 宽度 / height 高度路径绝对路径相对路径&#xff08;常…...

全流程基于最新导则下的生态环境影响评价技术方法及图件制作与案例实践

根据最新生态环境影响评价导则&#xff0c;结合生态环评内容庞杂、综合性强的特点&#xff0c;以既包括陆域、又包括水域的项目为主要案例&#xff0c;对生态环评的具体流程及所需内容进行系统阐述。利用Rstudio、Fragstats等软件分析计算生态环评中所需各种指数&#xff0c;利…...

【Spring】Spring缓存注解@Cacheable、@CacheEvict、@CachePut使

文章目录1 基于注解的支持1.1 Cacheable1.1.1 value属性指定Cache名称1.1.2 使用key属性自定义key1.1.3 condition属性指定发生的条件1.2 CachePut1.3 CacheEvict1.3.1 allEntries属性1.3.2 beforeInvocation属性1.4 Caching1.5 使用自定义注解2 配置Spring对Cache的支持2.1 声…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...