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

Java中的代理模式(一)

大家好👋,我是极客涛😎,今天我们聊一聊java中的代理模式,话不多说,还是老思路,什么是代理模式,为什么要有代理模式,如何实现代理模式

代理模式

在说java中的代理模式之前,我们可以先想一想生活的例子,这里也是一个加深自己对程序设计理解的一种学习方式,程序本质上就是对生活的抽象和实现。

生活中的代理模式太多了:

  • 我想租房,不需要自己去网上搜,找个中介,把需求讲清楚,房子就找好了
  • 我想吃饭,点个外卖外卖员就送上门了,我就可以直接吃了,不用自己去拿

这里如果我们进行抽象的话,对于租房来说,我本身只有判断房子适不适合我的能力,但是我没有(不想)对房源进行检索的能力,这时候中介其实就是代理了我对房源进行检索,但最终房子适不适合还是我自己决定;对点外卖来说,我不想自己去店里拿,所以外卖小哥代理了我帮把饭送到我手上,我自己用吃的能力。

也就是说,代理模式的核心就是对被代理对象的能力拓展。

代理方式

静态代理

我们拿我吃饭的场景举例说明

  • 定义一个Person接口,有吃的能力
  • 定义实现类GeekTao,代表我自己,实现了吃的能力
  • 定义实现类Taker,代表外卖员,外卖员除了有吃的能力,自己还有送外卖的专属能力
/*** 人*/
public interface Person {/*** 吃*/void eat();
}/*** 我*/
public class GeekTao implements Person {@Overridepublic void eat() {System.out.println("我自己吃饭");}
}/*** 外卖员*/
public class Taker implements Person {private final Person me;public Taker() {me = new GeekTao();}@Overridepublic void eat() {// 送外卖this.send();// 吃饭me.eat();}private void send() {System.out.println("外卖员把外卖送到家");}
}

测试方法

public class ProxyTest {public static void main(String[] args) {Person taker = new Taker();taker.eat();}
}

运行结果

外卖员把外卖送到家
我自己吃饭

真好,现在可以不用自己去拿外卖,外卖小哥就把外卖送到了;还有个问题,吃完我又口渴了,如果我还想喝,抽象一个drink方法,外卖小哥是不是还得实现一个drink方法?下边做个简单示例。

/*** 外卖员*/
public class Taker implements Person {private final Person me;public Taker() {me = new GeekTao();}@Overridepublic void eat() {// 送外卖this.send();// 吃饭me.eat();}private void send() {System.out.println("外卖员把外卖送到家");}@Overridepublic void drink() {// 送外卖this.send();// 喝水me.drink();}
}

以上实现其实就是静态代理,核心在于“静态”,对于我来说外卖小哥要实现一次,除了我还有很多人也需要点外卖,那外卖小哥每个都要适配一次;每次我自己有了新的需求(方法),外卖小哥也要跟着实现,但其实对于他来说实现方法都一样(都是送外卖),所以这也是静态代理的缺点,非常不灵活。

动态代理

还是拿我吃饭的场景举例子,上边说到外卖小哥不只是给我送外卖,那如何实现一个小哥可以给不同的人送外卖呢?

  • 定义一个Person接口,有吃的能力
  • 定义实现类GeekTao,代表我自己,实现了吃的能力
  • 定义实现类XiaoMing,也实现了吃的能力,也需要点外卖
  • 定义实现类TakerCommon,代表外卖员,外卖员除了有吃的能力,自己还有送外卖的专属能力,并且不只是可以给我送外卖,还可以给其他人送

其它类和上边例子一样,只贴了TakerCommon。

/*** 通用外卖员*/
public class TakerCommon implements InvocationHandler {private Object proxyTarget;public Object sendWho(Object target) {this.proxyTarget = target;return Proxy.newProxyInstance(proxyTarget.getClass().getClassLoader(), proxyTarget.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("外卖员送外卖给 " + proxyTarget.getClass().getSimpleName());return method.invoke(proxyTarget, args);}
}

测试方法

public class ProxyTest {public static void main(String[] args) {TakerCommon takerCommon = new TakerCommon();Person me = (Person) takerCommon.sendWho(new GeekTao());me.eat();System.out.println("========================");Person xiaoming = (Person) takerCommon.sendWho(new XiaoMing());xiaoming.eat();}
}

测试结果

外卖员送外卖给 GeekTao
我自己吃饭
========================
外卖员送外卖给 XiaoMing
小明吃饭

这时候我又想喝,那直接调用drink方法就行了,因为对于外卖小哥来说都是一样的。

测试方法

public class ProxyTest {public static void main(String[] args) {TakerCommon takerCommon = new TakerCommon();Person me = (Person) takerCommon.sendWho(new GeekTao());me.eat();me.drink();System.out.println("========================");Person xiaoming = (Person) takerCommon.sendWho(new XiaoMing());xiaoming.eat();xiaoming.drink();}
}

测试结果

外卖员送外卖给 GeekTao
我自己吃饭
外卖员送外卖给 GeekTao
我自己喝
========================
外卖员送外卖给 XiaoMing
小明吃饭
外卖员送外卖给 XiaoMing
小明在喝

总结

代理模式的核心就是对被代理对象的能力拓展

静态代理适合简单业务,不经常变动,因为实现逻辑简单,开发成本低

动态代理适合变动可能性较大的业务。

相关文章:

Java中的代理模式(一)

大家好👋,我是极客涛😎,今天我们聊一聊java中的代理模式,话不多说,还是老思路,什么是代理模式,为什么要有代理模式,如何实现代理模式 代理模式 在说java中的代理模式之前…...

跳跃游戏-算法

题目 给定一个数组nums {1,2,3,4,5},每个元素nums[i]表示从i这个位置最多可以向前跳跃nums[i]个台阶,求最小需要跳几次就可以调到末尾 思路 反向查找 从末尾开始逐个向前判断最远的起跳位置,接着再以该位置递归的判断 public int jumpT…...

ERP系统哪个好用?用友,金蝶,ORACLE,SAP综合测评

ERP系统哪个好用?用友,金蝶,ORACLE,SAP综合测评 ERP领域SAP、ORACLE相对于国内厂商如用友、金蝶优势在哪? SAP,ORACLE操作习惯一般国人用不惯;相对于国产软件,界面也很难看&#x…...

外汇天眼:美国证券交易委员会(SEC)采纳了一系列规定,以加强与特殊目的收购公司(SPACs)相关的投资者保护

美国证券交易委员会(SEC)今天通过了一系列新规和修订,以增强特殊目的收购公司(SPACs)的首次公开募股(IPOs)中的披露,并在SPACs与目标公司之间的后续业务合并交易(de-SPAC…...

kotlin map 与 flatmap

kotlin map 与 flatmap 是2个不同的概念的 map 是一种数据结构,flatmap 是一个高阶函数,处理集合用的 Map Map 是一种数据结构,它由一系列的键值对组成,每个键都是唯一的,并且与一个特定的值相关联。你可以通过键来…...

nginx-rtmp-module 支持 Enhancing RTMP HEVC(H.265)

Enhancing RTMP, FLV 2023年7月31号正式发布,主要支持了HEVC(H.265)、VP9、AV1视频编码,发布差不多半年了,很多开源项目已支持,最近打算播放和推送端也支持下,想找个支持的rtmp server方便测试用,但没找到合…...

2024最新JDK1.8+JDK17+JDK21安装包下载+文档

2024年更新,JDK8的64位和32位安装包都有,Java8最新文档也有,JDK17和JDK21的最新安装包也有 因为网上的安装包都不是最新的,所以自己去Oracle官网登录下载保存了一份,需要的朋友下面网盘链接下载 JDK8—64位安装程序&…...

如何利用chatgpt提升工作效率

chatgpt全领域小助手 项目管理:制定项目计划、跟踪进度、分配任务和记录里程碑。客户服务:回答常见问题、提供产品支持和处理客户投诉,提升客户满意度。销售支持:提供销售培训、销售脚本和客户资料,辅助销售团队进行销…...

WinSCP下载安装并实现远程SSH本地服务器上传文件

文章目录 1. 简介2. 软件下载安装:3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 ​ Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件,它的主要功能是在本地与远程计…...

QEMU搭建arm虚拟机开发环境

获取QEMU代码 git clone https://gitlab.com/qemu-project/qemu.git 切换对应的工程分支 使用git指令切换到对应的分支上,我这里使用的是stable-4.0的分支 git checkout -b stable-4.0 remotes/origin/stable-4.0 配置&编译 在工程的根目录下执行 ./conf…...

web 应用常见的安全问题

一xss攻击 人们经常将跨站脚本攻击(Cross Site Scripting)缩写为CSS,但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为XSS。 跨站脚本攻击&#xff…...

502. IPO

502. IPO 题目链接&#xff1a;502. IPO 代码如下&#xff1a; //堆的使用 class Solution { public:int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {vector<pair<int,int>> mp;//优先队列默认的是大…...

如何安装MeterSphere并实现无公网ip远程访问服务管理界面

文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通…...

做FP独立站怎么引流?这个引流法宝收好了!

近年来&#xff0c;由于卖家数量飙升导致平台竞争持续升级&#xff0c;卖家之间的恶性循环竞争以及平台政策的不断调整等&#xff0c;造成了众多亚马逊等跨境卖家纷纷从平台转向独立站。可是&#xff0c;转型做独立站前要先考虑清楚独立站与平台二者之间的区别。 如果在第三方平…...

幻兽帕鲁PalWorld服务器搭建教程,1分钟开服,纯小白教程,无需基础

雨云面板服快速开幻兽帕鲁PalWorld服务器的教程&#xff0c;配置文件修改方法和配置项中文注释。 最近这游戏挺火&#xff0c;很多人想跟朋友联机&#xff0c;如果有专用服务器&#xff0c;就不需要房主一直开着电脑&#xff0c;稳定性也好得多。 幻兽帕鲁简介 《幻兽帕鲁》…...

算法小抄01

1. 计数排序是一种基于 统计 的排序算法 2. 基于比较的排序算法有&#xff1a;&#xff08;1&#xff09;直接插入排序&#xff1b;&#xff08;2&#xff09;冒泡排序&#xff1b;&#xff08;3&#xff09;简单选择排序&#xff1b;&#xff08;4&#xff09;希尔排序&#…...

Spring Boot 集成 API 文档 - Swagger、Knife4J、Smart-Doc

文章目录 1.OpenAPI 规范2.Swagger: 接口管理的利器3.Swagger 与 SpringFox&#xff1a;理念与实现4.Swagger 与 Knife4J&#xff1a;增强与创新5.案例&#xff1a;Spring Boot 整合 Swagger35.1 引入 Swagger3 依赖包5.2 优化路径匹配策略兼容 SpringFox5.3 配置 Swagger5.4 S…...

2024年软考报名时间及条件,小白必看

不少考生开始准备报名2024年软件水平考试&#xff0c;那么报名软考有没有学历、专业以及工作经验等方面的限制呢?今天就给大家梳理下2024年软考考试&#xff0c;若有变更&#xff0c;也会及时更新内容。 免费送备考资料。联系我 2024年软考考试时间 2024年软考有两次考试&a…...

vue 跨域XMLHttpRequest

vue 跨域 使用XMLHttpRequest 亲测好使 let url=http://127.0.0.1:9000/pssnotifyyb?b=1//url=https://api.j4u.ink/v1/store/other/proxy/remote/moyu.jsonvar xhr=new XMLHttpRequest()xhr.open(GET,url,true)//第三个参数是是否异步请求,默认true xhr.onreadyst…...

【正点原子STM32】STM32基础知识(F1F4F7H7 STM32系统框架、寻址范围、存储器映射的存储器功能划分、寄存器映射)

一、STM32系统框架 1.1、Cortex M内核 & 芯片1.2、F1系统架构1.3、F4系统架构1.4、F7系统架构1.5、H7系统架构 二、STM32的寻址范围&#xff1f; 三、存储器映射 存储器功能划分&#xff08;F1为例&#xff09;STM32F1存储器映射图 四、寄存器映射 寄存器基础知识STM3…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...