【代理模式使用场景】
一般来说,代理模式使用场景是远程代理、虚拟代理、安全代理等。下面来详细介绍下这三个场景是什么,实现原理和特点。不过在介绍三个场景前,我们还是先来回顾下代理模式。
代理模式
定义
是结构型设计模式,引入一个对象控制对另一个对象的访问。代理对象在客户端和目标对象之间起到中介的作用,它可以在不改变目标对象的情况下,为目标对象添加额外的功能或者控制对目标对象的访问。
远程代理
定义
为一个位于不同地址空间的对象提供本地代表,隐藏网络通信的细节。
原理
1.定义远程接口
首先确定远程对象提供的服务,定义一个接口,该接口描述了远程对象能够执行的方法。例如:
public interface RemoteServiceInterface {void doSomething();}
2.实现远程接口的服务端类
在服务端实现这个接口,提供具体的服务逻辑。例如:
public class RemoteServiceImpl implements RemoteServiceInterface {@Overridepublic void doSomething() {System.out.println("执行远程服务端的操作");}}
3.生成远程对象的 stub 和 skeleton
使用 Java 的远程方法调用(RMI)技术时,需要通过工具生成 stub(存根)和 skeleton(骨架)。Stub 是在客户端的代理对象,它负责将方法调用转换为网络请求并发送到服务端。Skeleton 是在服务端的对象,它接收来自客户端的请求并调用实际的远程对象方法。
4.启动服务端
在服务端启动一个 RMI 注册表,并将远程对象绑定到注册表上,以便客户端能够找到它。例如:
public class RemoteServer {public static void main(String[] args) {try {RemoteServiceInterface service = new RemoteServiceImpl();java.rmi.Naming.rebind("rmi://localhost:1099/RemoteService", service);System.out.println("远程服务已启动");} catch (Exception e) {e.printStackTrace();}}}
5.客户端调用远程代理
在客户端,通过查找注册表获取远程对象的代理,并调用远程方法。例如:
public class RemoteClient {public static void main(String[] args) {try {RemoteServiceInterface service = (RemoteServiceInterface) java.rmi.Naming.lookup("rmi://localhost:1099/RemoteService");service.doSomething();} catch (Exception e) {e.printStackTrace();}}}
特点
一、透明性
- 对于客户端而言,使用远程代理与使用本地对象几乎没有区别。你可以像调用本地方法一样调用远程对象的方法,而不需要关心底层的网络通信细节。
- 这种透明性使得开发人员可以更加专注于业务逻辑的实现,而不必过多地考虑远程调用的复杂性。
二、位置独立性
- 客户端不需要知道远程对象的实际物理位置。你只需要知道如何通过代理来访问远程对象,而代理会负责处理与远程对象的通信。
- 这使得系统具有更好的可扩展性和灵活性,因为可以将远程对象部署在不同的服务器上,而不会影响客户端的代码。
三、网络通信管理
- 远程代理负责处理网络通信的细节,包括建立连接、发送请求和接收响应等。你无需自己处理这些底层的网络操作,大大简化了开发过程。
- 它可以根据网络状况进行优化,例如使用缓存、压缩数据等技术来提高通信效率。
四、安全性增强
- 可以在远程代理中实现安全机制,对客户端的访问进行授权和认证。你可以限制只有特定的客户端才能访问远程对象,从而提高系统的安全性。
- 还可以对传输的数据进行加密,防止数据在网络传输过程中被窃取或篡改。
五、负载均衡和故障转移
- 在分布式系统中,可以使用多个远程对象的副本,并通过远程代理实现负载均衡。你可以将请求分发到不同的服务器上,以提高系统的性能和可用性。
- 当某个服务器出现故障时,远程代理可以自动将请求转发到其他正常的服务器上,实现故障转移,从而提高系统的可靠性。
虚拟代理
定义
根据需要创建开销很大的对象,延迟对象的创建直到真正需要的时候。通过它来存放实例化需要很长时间、真实对象创建很耗费系统资源或者根本不存在的对象的引用。
原理
1.定义主题接口
确定被代理对象的行为,定义一个接口。例如:
public interface Image {void display();}
实现真实对象类
这是最终要被代理的对象,它实现了主题接口。例如:
public class RealImage implements Image {private String fileName;public RealImage(String fileName) {this.fileName = fileName;loadFromDisk();}private void loadFromDisk() {System.out.println("正在从磁盘加载图像:" + fileName);}@Overridepublic void display() {System.out.println("显示图像:" + fileName);}}
3.实现虚拟代理类
虚拟代理类也实现主题接口,在其中保存对真实对象的引用或者创建真实对象的条件。当需要真正调用真实对象的方法时,才创建真实对象。例如:
public class VirtualImage implements Image {private String fileName;private RealImage realImage;public VirtualImage(String fileName) {this.fileName = fileName;}@Overridepublic void display() {if (realImage == null) {realImage = new RealImage(fileName);}realImage.display();}}
4.客户端使用虚拟代理
在客户端,使用虚拟代理来代替真实对象进行操作。例如:
public class Client {public static void main(String[] args) {Image image = new VirtualImage("big_image.jpg");// 首次调用,会触发真实对象的创建和加载image.display();// 再次调用,直接使用已创建的真实对象image.display();}}
特点
安全代理
定义
基于不同的权限控制对真实主题的访问,保证系统的安全性。
原理
安全代理的核心是在客户端与真实对象之间插入一个代理对象,这个代理对象负责对客户端的请求进行安全检查和控制。
通常,安全代理会实现与真实对象相同的接口,这样客户端可以像使用真实对象一样使用安全代理。当客户端调用安全代理的方法时,代理对象会首先进行一系列的安全检查,比如验证用户身份、检查用户权限等。如果安全检查通过,代理对象会将请求转发给真实对象进行处理,并将真实对象的返回结果返回给客户端;如果安全检查不通过,代理对象可以拒绝请求或者抛出异常。
例如,在一个文件访问系统中,安全代理可以在用户尝试打开文件之前,检查用户是否具有打开该文件的权限。如果用户有权限,安全代理会调用真实的文件对象打开文件并返回结果;如果用户没有权限,安全代理会拒绝打开文件并抛出权限不足的异常。
特点
- 增强安全性:通过在客户端与真实对象之间增加一层安全检查,可以有效地防止未经授权的访问和恶意操作,提高系统的安全性。你不必在每个真实对象的方法中都编写安全检查代码,减少了代码的重复和复杂性。
- 可定制性:可以根据具体的安全需求定制安全代理的行为。例如,可以根据不同的用户角色、访问场景等设置不同的安全策略。你可以灵活地调整安全代理的安全检查逻辑,以适应不同的安全要求。
- 透明性:对于客户端来说,使用安全代理与直接使用真实对象的方式基本相同,客户端不需要关心安全代理的存在,从而实现了安全机制的透明性。这使得安全代理可以很容易地集成到现有的系统中,而不会对客户端的代码造成太大的影响。
相关文章:
【代理模式使用场景】
一般来说,代理模式使用场景是远程代理、虚拟代理、安全代理等。下面来详细介绍下这三个场景是什么,实现原理和特点。不过在介绍三个场景前,我们还是先来回顾下代理模式。 代理模式 定义 是结构型设计模式,引入一个对象控制对另…...
ARM-8 代码还原动态调试之 pstree 条件表达式
out_string(lvl level - 1 ? last ? sym->last_2 : sym->branch_2 : more[lvl 1] ? sym->vert_2 : sym->empty_2); 条件表达式执行顺利: lvl level - 1 ? last ? sym->last_2 : sym->branch_2 : more[lvl 1] ?…...
Spring Boot技术栈在电影评论网站中的应用
2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…...
DDOS防护
DDoS攻击简介 分布式拒绝服务(DDoS)攻击是一种网络攻击方式,通过控制大量的受感染系统(称为“僵尸网络”)向目标服务器发送大量的网络流量或请求,目的是使目标服务器超载,无法提供正常服务。这…...
【Vue】Vue(九)OptionsAPI与CompositionAPI的区别
文章目录 OptionsAPI与CompositionAPI在代码使用和逻辑上的区别一、代码使用方面的区别(一)组件定义的结构(二)响应式数据的定义与使用(三)逻辑复用的实现方式 二、逻辑方面的区别(一࿰…...
MySQL 【日期】函数大全(四)
目录 1、MAKEDATE() 根据年份和一年中天数创建一个日期并返回。 2、MAKETIME() 指定的时、分、秒创建一个时间并返回。 3、MINUTE() 函数提取并返回时间的分钟部分。 4、MONTH() 函数提取日期的月份部分并作为数字返回。 5、MONTHNAME() 返回给定日期的月份的名字。 6、N…...
Jlink 直接读取单片机数据
1. 驱动版本 因人而异,这里我使用的是 “J-Flash V6.96” 本人驱动链接:夸克网盘 提取码:rgzk 2. 打开软件 3. 创建jlink工程 4. 选择芯片 此处本人使用芯片 “STM32F103VCT6” 5. 连接单片机 连接成功反馈 6. 读取单片机内部数据 …...
VScode运行C语言终端输出中文乱码问题解决方案
VScode运行C语言输出中文乱码问题解决方案 由于 VSCode 的终端是对系统的 cmd 命令行工具的调用,而 cmd 的默认编码为 GBK。当我们在 VSCode 中以 UTF-8 编码进行代码编写且代码里含有中文字符时,在终端运行代码便会出现中文乱码现象。要解决此问题&…...
Leetcode刷题. 贪心算法
贪心算法: 比较传统的解释:将整个问题拆解为几个小问题,找到小问题的最优解,加起来就是整个问题的全局最优解。对于现在的我理解贪心就是一种感觉,给出证明很难,解题思路一般就是认真读题,发掘题…...
强化学习的数学原理-01基本概念
state: T h e s t a t u s o f a g e n t w i t h r e s p e c t t o t h e e n v i r o n m e n t The \quad status \quad of \quad agent \quad with \quad respect \quad to \quad the \quad environment Thestatusofagentwithrespecttotheenvironment (agent 相对于环境的…...
D41【python 接口自动化学习】- python基础之函数
day41 函数参数传递错误 学习日期:20241018 学习目标:函数﹣-54 避坑指南:列表作为参数传递出错了怎么办? 学习笔记: 列表类型的特殊性 list1[x,y,z] tuple1(list1,b,c)# 修改元组中的列表,会…...
思迅商云8修改最大找零金额
执行如下语句前请备份数据库 -POS收银找零金额最大数 --把下面SQL中的 1000.00 改成你想要的金额数,再到查询分析器中执行: --总店 use hbposv8 go insert t_sys_system (sys_var_id, sys_var_value, sys_var_name) values (pos_max_givchg, 1000.00, 最…...
Lumerical学习——分析工具(Analysis tools)
一、分析工具和模拟环境(Analysis tools and the simulation environment) 模拟计算完成后,模拟计算数据紧接着写到模拟工程文件中;甚至当模拟计算提前结束时计算得到的部分数据集也会写到文件中。当模拟完成后单击退出按钮、或者…...
思迅商云8会员积分全部清0
请您备份数据库后执行以下语句: declare card_id varchar(20), acc_num numeric(16,4), dec_num numeric(16,4), minus_num numeric(16,4), branch_no varchar(4), count int select branch_nosys_var_value fro…...
$nextTick原理
一、什么是 $nextTick $nextTick 是 Vue 实例上的一个方法,允许我们在下次 DOM 更新循环结束后执行一个回调。这通常用于需要访问更新后的 DOM状态的场景。由于 Vue 在数据变化后并不会立即更新 DOM,而是进行异步批处理,使用 $nextTick可以保…...
python办公:批量PDF合并—通用版
目录 专栏导读1、库的介绍2、库的安装3、核心代码3、提供测试PDF生成代码5、完整代码进阶版总结 专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️🌈 博客主页:请点击——> 一…...
人工智能研究创造出新型蛋白质
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
blender 金币基站 建模 学习笔记
一、学习blender视频教程链接 案例3:金币基站_建模_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Bt4y1E7qn?vd_sourced0ea58f1127eed138a4ba5421c577eb1&p12&spm_id_from333.788.videopod.episodes 二、金币基站建模过程 (1&#x…...
eggjs sequelize egg-sequelize-auto自动从零生成一个数据表 自动创建model
sequelize egg-sequelize-auto整个过程还是有一些坑 包括兼容性问题 依赖安装问题 需要注意 缺少一个条件 包跑不起来 或使用体验很差 1. 全局安装插件 pnpm install -g sequelize-cli sequelize mysql2 egg-sequelize-auto 2. 执行命令创建 migrate迁移文件 以及 mod…...
解决低版本pytorch和onnx组合时torch.atan2()不被onnx支持的问题
解决这个问题,最简单的当然是升级pytorch和onnx到比较高的版本,例如有人验证过的组合: pytorch2.1.1cu118, onnxruntime1.16.3 但是因为你的模型或cuda环境等约束,不能安装这么高的版本的pytorch和onnx组合时(例如我的环境是pytorch1.12&…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: 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:…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
spring boot使用HttpServletResponse实现sse后端流式输出消息
1.以前只是看过SSE的相关文章,没有具体实践,这次接入AI大模型使用到了流式输出,涉及到给前端流式返回,所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...
【技巧】dify前端源代码修改第一弹-增加tab页
回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码,在知识库增加一个tab页"HELLO WORLD",完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...
