当前位置: 首页 > 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 声…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

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

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

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...