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

一天攻克一个知识点 —— 设计模式之动态代理

一、设计模式之代理设计

代理设计是在Java开发中使用较多的一种设计模式,所谓的代理设计模式就是指一个代理主体操作真实主体,真实主体操作具体业务,代理主体负责给具体业务添砖加瓦。
就好比在生活中你有一套房子想要出租(你=真实主体),你找了房产中介(中介=代理主体)。真实主体负责提供房屋和收钱,代理主体负责带客户看房 、扣除手续费。租客只管租房子和付款,至于谁提供的房子并不关心。

我们发现,只需要定义一个租赁的接口,真实主体与代理主体都可以实现此接口,然后再由代理主体操作真实主体即可,上面的要求可以形成如下的代码:

1. 定义租赁接口

package com.javabasic.proxy;/*** 定义抽象接口*/
public interface House {/*** 定义抽象方法 租赁*/void rent();
}

2. 定义真实主体 - 房东

package com.javabasic.proxy;/*** 定义真实主体 房东*/
public class Owner implements House{@Overridepublic void rent() {System.out.println("房东提供房子,收取租金200元/月");}
}

3. 定义代理主体 - 中介

package com.javabasic.proxy;/*** 定义代理主体 中介*/
public class Agent implements House{// 接收真实主体 房东private House house;/*** 通过构造方法,让中介与房东之间产生联系。* 根据Java动态绑定机制,House运行时的真实类型是房东类型,就可以获取到房东的出租行为。* @param house*/public Agent(House house){this.house = house;}/*** 中介对房东出租业务进行增强*/@Overridepublic void rent() {rentBefore();house.rent(); // 房东 出租rentAfter();}private void rentBefore(){System.out.println("中介负责寻找租客、带看、保存租客信息、签合同、收取租金。");}private void rentAfter(){System.out.println("中介负责租客退租后的清扫工作。");}}

4. 主程序 中介出租房屋

在这里插入图片描述

二、动态代理

上面讲解的代理机制的操作,属于静态代理,因为每一个代理类只能为一个接口服务,这样程序开发中必然会产生过多的代理类。最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理功能。

Java 中想要实现动态代理的机制,则需要java.lang.reflect.InvocationHandler接口java.lang.reflect.Proxy类的支持。

InvocationHandler接口的定义如下:

package java.lang.reflect;public interface InvocationHandler {public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
}

Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类。

	/*ClassLoader loader : 类加载器Class<?>[] interfaces : 得到真实类实现的全部接口InvocationHandler h : 得到InvocationHandler子类实例*/@CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException{...}

房屋租赁代码修改如下 :

1. 需要房东实现租赁的接口

public interface House {/*** 定义抽象方法 租赁*/void rent();
}public class Owner implements House{@Overridepublic void rent() {System.out.println("房东提供房子,收取租金200元/月");}
}

2. 创建代理类(InvocationHandler / Proxy)

package com.javabasic.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class Agent2 implements InvocationHandler {// 接收真实主体private Object obj;// 对外提供绑定真实主体方法public Object bind(Object obj){this.obj = obj;// 通过真实对象创建代理对象并返回给调用者。/*Proxy.newProxyInstance : 三个参数类加载器 :  this.obj.getClass().getClassLoader()真实类型实现的所有接口 : this.obj.getClass().getInterfaces()代理类  : thisreturn 代理对象*/Object object = Proxy.newProxyInstance(this.obj.getClass().getClassLoader(),this.obj.getClass().getInterfaces(), this);System.out.println("bind之后object真实类型 = " + object.getClass().getName());return object;}/*** 代理类会执行的方法。* @param proxy 代理主体* @param method 调用的方法* @param args 方法的参数** @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("proxy真实类型 = " + proxy.getClass().getName());rentBefore();method.invoke(this.obj, args); // 通过反射执行真实主体方法rentAfter();return null;}private void rentBefore(){System.out.println("中介负责寻找租客、带看、保存租客信息、签合同、收取租金。");}private void rentAfter(){System.out.println("中介负责租客退租后的清扫工作。");}
}

3. 主程序 出租

在这里插入图片描述

相关文章:

一天攻克一个知识点 —— 设计模式之动态代理

一、设计模式之代理设计 代理设计是在Java开发中使用较多的一种设计模式&#xff0c;所谓的代理设计模式就是指一个代理主体操作真实主体&#xff0c;真实主体操作具体业务&#xff0c;代理主体负责给具体业务添砖加瓦。 就好比在生活中你有一套房子想要出租(你真实主体)&…...

数据采集与预处理【大数据导论】

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 数据采集与预处理前 必看 【大数据导论】—大数据序…...

白骑士的PyCharm教学进阶篇 2.2 高级调试技术

系列目录 上一篇&#xff1a;白骑士的PyCharm教学进阶篇 2.1 高效编码技巧 在Python开发中&#xff0c;调试是一个非常重要的环节。PyCharm作为一款功能强大的IDE&#xff0c;不仅提供了基本的调试功能&#xff0c;还包含了许多高级调试工具与技巧。本篇将详细介绍这些高级调试…...

[网鼎杯]2018Unfinish

使用ctf在线靶场https://adworld.xctf.org.cn/home/index。 进入靶场&#xff0c;发现是一个登录页面。 使用awvs进行扫描&#xff0c;发现存在login.php和register.php&#xff0c;并且register.php存在sql注入漏洞。 访问一下register.php试试&#xff0c;发现是一个注册页面…...

Java算法-力扣leetcode-383. 赎金信

383. 赎金信 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a…...

使用idea对spring全家桶的各种项目进行创建

目录 1. 简介2. spring2.1 简介2.2 创建 3. springmvc3.1 介绍3.2 创建 4. springboot4.1 简介4.2 创建&#xff08;仅仅就其中一种&#xff09; 5. 其他&#xff1a;maven6. 参考链接 1. 简介 因为总是分不清spring全家桶&#xff0c;所以就在这里进行一个总结。 2. spring …...

FAT32、NTFS、FAT的区别

FAT&#xff08;File Allocation Table&#xff09; 特点 簇大小限制&#xff1a;FAT文件系统的簇大小是固定的&#xff0c;这限制了单个文件的大小和文件系统的效率。 存储效率&#xff1a;由于簇大小的限制&#xff0c;FAT文件系统在存储小文件时可能会浪费空间。 文件系统结…...

捉虫笔记(二)之 杀软请你自重点

捉虫笔记&#xff08;二&#xff09;之 杀软请你自重点 前一篇文章介绍了如何配置符号&#xff0c;这一篇文章我们来个实战。 1 现象 在我们的程序中利用robocopy进行文件的复制。但是QA反馈&#xff0c;只要进行了备份操作&#xff0c;整个进程就会卡住。但是奇怪的是只有他…...

python学习之路 - python的函数

目录 一、python函数1、函数介绍2、函数的定义3、函数的参数4、函数的返回值5、函数说明文档6、函数的嵌套调用7、变量的作用域8、综合案例9、函数与方法的区别 二、python函数进阶1、函数多返回值2、函数多种传参方式a、位置参数b、关键字参数c、缺省参数d、不定长参数 3、匿名…...

使用SpringBoot+Vue3开发项目(2)---- 设计文章分类的相关接口及页面

目录 一.所用技术栈&#xff1a; 二.后端开发&#xff1a; 1.文章分类列表渲染&#xff1a; 2.新增文章分类&#xff1a; 3.编辑文章分类&#xff1a; 4.删除文章分类 &#xff1a; 5.完整三层架构后端代码&#xff1a; &#xff08;1&#xff09;Controller层&#xff1a…...

Layui---toolbar与 tool的区别

table.on(toolbar): table.on(toolbar)&#xff1a; 这个事件监听器是用来处理表格工具栏的事件。工具栏通常位于表格的上方&#xff0c;可以包含添加、删除、导出等按钮。当用户与这些工具栏中的按钮交互时&#xff0c;比如点击一个按钮来添加新行或者进行搜索操作&#xff0c…...

U-Net++原理与实现(含Pytorch和TensorFlow源码)

U-Net原理与实现 引言1. U-Net简介1.1 编码器&#xff08;Encoder&#xff09;1.2 解码器&#xff08;Decoder&#xff09;1.3 跳跃连接&#xff08;Skip Connections&#xff09; 2. U-Net详解2.1 密集跳跃连接2.2 嵌套和多尺度特征融合2.3 参数效率和性能2.4 Pytorch代码2.5 …...

产品心理学:啦啦队效应

电视里我们常会看见这样一个场景&#xff0c;一群女孩穿着短裙有说有笑地在大街上走过&#xff0c;把路人们都看傻了&#xff0c;其实单个来看&#xff0c;她们的长相并不出众&#xff0c;可是凑在一起就显得青春貌美&#xff0c;这就是“啦啦队效应”——cheerleader effect。…...

AC+AP组网

配置DHCP Switch1 <Huawei>sys [Huawei]undo in en [Huawei]vlan batch 10 20 30 40[Huawei]int vlan 10 [Huawei-Vlanif10]ip add 192.168.10.1 24 [Huawei-Vlanif10]quit[Huawei]int vlan 20 [Huawei-Vlanif20]ip add 192.168.20.1 24 [Huawei-Vlanif20]quit[Huawei]…...

2024.8.05(glibc的安装及MySQL的安全用户角色权限)

一、glibc的安装 1、清空/etc目录下的my.cnf [rootlocalhost ~]# ls -l /etc/my.cnf -rw-r--r--. 1 root root 570 6月 8 2017 /etc/my.cnf [rootlocalhost ~]# rm -rf /etc/my.cnf 2、删除mariadb [rootlocalhost ~]# yum -y remove mariadb [rootlocalhost ~]# find / -na…...

【精选】6款一键生成论文的软件3000字论文网站

千笔-AIPassPaPer是一款功能强大且全面的AI论文写作工具&#xff0c;特别适合学术研究者和学生使用。它不仅能够一键生成高质量的论文初稿&#xff0c;还涵盖了700多个学科专业方向&#xff0c;满足各种学术需求。 一、千笔-AIPassPaPer 传送门&#xff1a;https://www.aipape…...

如何使用 PHP Simple HTML DOM Parser 轻松获取网页中的特定数据

背景介绍 网页数据的抓取已经成为数据分析、市场调研等领域的重要工具。无论是获取产品价格、用户评论还是其他公开数据&#xff0c;网页抓取技术都能提供极大的帮助。今天&#xff0c;我们将探讨如何使用 PHP Simple HTML DOM Parser 轻松获取网页中的特定数据。PHP Simple H…...

Linux笔记 --- 传统链表

目录 链表 单向链表 单向循环链表 双向链表 设计表 初始化 在auchor后插入节点&#xff0c; 在auchor前插入节点 删除节点 传统链表 通过使用链表我们可以将一个数组中的数据分开到不同位置存放并使用指针指向他们&#xff0c;使之逻辑相连&#xff0c;解决了顺序存储所需要…...

C语言的编译(预处理操作)+链接

目录 翻译环境和执行环境 预定义符号 #define定义标识符 续行符\ #define定义宏 再说一下&#xff0c;#define其实就是替换 #和## 宏和函数的对比 命名约定 #undef 命令行定义 条件编译 文件包含 避免头文件重复引用&#xff0c;否则会增加代码长度 翻译环境和执行环境 在C中存…...

FFmpeg实战 - 解复用与解码

大纲目录 文章目录 前置知识音视频基础概念解复用、解码的流程分析FFMPEG有8个常用库 常见音视频格式的介绍aac格式介绍&#xff08;ADTS&#xff09;h264格式分析FLV和MP4格式介绍 FFmpeg解码解封装实战数据包和数据帧&#xff08;AVPacket/AVFrame&#xff09;AVPacket/AVFra…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...