Spring 学习(六)代理模式
10. 代理模式
- 案例

10.1 静态代理
-
角色分析
- 抽象角色:一般使用接口或者抽象类实现。
- 真实角色:被代理的角色。
- 代理角色:代理真实角色,含附属操作。
- 客户:访问代理对象的角色。
-
租房案例
-
定义租赁接口
/*** TODO* 租房* @author why* @since 2021/7/6 9:06*/ public interface Rent {public void rent(); } -
定义真实角色
/*** TODO* 房东* @author why* @since 2021/7/6 9:10*/ public class Landlord implements Rent {public void rent() {System.out.println("房东要出租房子");} } -
定义代理角色
/*** TODO* 中介* @author why* @since 2021/7/6 9:14*/ public class Proxy implements Rent {private Landlord landlord;public Proxy() {}public Proxy(Landlord landlord) {this.landlord = landlord;}/*** 出租房子*/public void rent() {seeHouse();landlord.rent();signContract();fee();}/*** 看房*/public void seeHouse(){System.out.println("中介带租客看房");}/*** 收中介费*/public void fee(){System.out.println("收中介费");}/*** 签合同*/public void signContract(){System.out.println("签租赁合同");}} -
客户端访问代理角色
/*** TODO* 租客* @author why* @since 2021/7/6 9:12*/ public class Client {public static void main(String[] args) {// 房东想要出租房子Landlord landlord = new Landlord();// 中介帮助房东出租房子,包含了附加操作Proxy proxy = new Proxy(landlord);// 租客找中介租房子proxy.rent();} }
-
-
模式优点
- 可以使真实角色的操作更加纯粹,不必关注一些公共业务。
- 公共业务交给代理角色,实现了业务的分工。
- 公共业务发生扩展时,方便集中管理。
-
模式缺点
- 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低。
-
业务模拟
-
抽象 AOP 机制

-
定义用户操作接口
/*** TODO* 用户服务接口* @author why* @since 2021/7/6 9:38*/ public interface UserService {public void add();public void delete();public void update();public void query(); } -
定义业务操作实现类
/*** TODO* 用户接口实现类(真实对象)* @author why* @since 2021/7/6 9:40*/ public class UserServiceImpl implements UserService {public void add() {System.out.println("增加一个用户");}public void delete() {System.out.println("删除一个用户");}public void update() {System.out.println("修改一个用户");}public void query() {System.out.println("查询一个用户");} } -
定义代理
/*** TODO* 代理* @author why* @since 2021/7/6 9:57*/ public class UserServiceProxy implements UserService {private UserService userService;public void setUserService(UserService userService) {this.userService = userService;}public void add() {log("add");userService.add();}public void delete() {log("delete");userService.delete();}public void update() {log("update");userService.update();}public void query() {log("query");userService.query();}// 日志方法public void log(String msg) {System.out.println("[Debug] 使用了"+ msg +"方法");} } -
定义客户端
/*** TODO* 客户端* @author why* @since 2021/7/6 9:44*/ public class Client {public static void main(String[] args) {UserServiceImpl userService = new UserServiceImpl();UserServiceProxy userServiceProxy = new UserServiceProxy();userServiceProxy.setUserService(userService);userServiceProxy.add();} }
-
10.2 动态代理
-
动态代理和静态代理的角色一样
-
动态代理的代理类是动态生成的,不需要编写。
-
动态代理分为基于接口的动态代理和基于类的动态代理。
- 基于接口 — JDK 动态代理
- 基于类 — CGLIB
- Java 字节码实现 — Javasist
-
租房案例
-
定义租赁接口
/*** TODO* 租房* @author why* @since 2021/7/6 9:06*/ public interface Rent {public void rent(); } -
定义真实角色(房东)
/*** TODO* 房东* @author why* @since 2021/7/6 9:10*/ public class Landlord implements Rent {public void rent() {System.out.println("房东要出租房子");} } -
构造代理类生成器
/*** TODO* 自动生成代理类* @author why* @since 2021/7/6 13:43*/ public class ProxyInvocationHandler implements InvocationHandler {// 被代理的接口private Rent rent;public void setRent(Rent rent) {this.rent = rent;}// 获得代理类public Object getProxy(){return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);}// 处理代理实例并返回结果public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 动态代理由反射机制实现Object result = method.invoke(rent, args);return result;} } -
定义客户端
/*** TODO* 客户端* @author why* @since 2021/7/6 13:54*/ public class Client {public static void main(String[] args) {// 真实角色Landlord landlord = new Landlord();// 代理角色(由 InvocationHandler 获取)ProxyInvocationHandler pih = new ProxyInvocationHandler();// 通过调用处理程序处理要调用的接口对象pih.setRent(landlord);Rent proxy = (Rent) pih.getProxy();proxy.rent();} }
-
-
模式优点
- 可以使真实角色的操作更加纯粹,不必关注一些公共业务。
- 公共业务交给代理角色,实现了业务的分工。
- 公共业务发生扩展时,方便集中管理。
- 一个动态代理类代理的是一个接口,一般就是一类业务。
- 一个动态代理可以代理多个类,前提是这些类实现了同一个接口。
-
业务模拟
-
定义用户操作接口
/*** TODO* 用户服务接口* @author why* @since 2021/7/6 9:38*/ public interface UserService {public void add();public void delete();public void update();public void query(); } -
定义业务操作实现类
/*** TODO* 用户接口实现类(真实对象)* @author why* @since 2021/7/6 9:40*/ public class UserServiceImpl implements UserService {public void add() {System.out.println("增加一个用户");}public void delete() {System.out.println("删除一个用户");}public void update() {System.out.println("修改一个用户");}public void query() {System.out.println("查询一个用户");} } -
定义代理生成器
/*** TODO* 自动生成代理类* @author why* @since 2021/7/6 13:43*/ public class ProxyInvocationHandler implements InvocationHandler {// 被代理的接口private Object target;public void setTarget(Object target) {this.target = target;}// 获得代理类public Object getProxy(){return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}// 处理代理实例并返回结果public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {log(method.getName());// 动态代理由反射机制实现return method.invoke(target, args);}public void log(String msg){System.out.println("执行了" + msg + "方法");} } -
定义客户端
/*** TODO* 客户端* @author why* @since 2021/7/6 15:00*/ public class Client {public static void main(String[] args) {UserServiceImpl userService = new UserServiceImpl();ProxyInvocationHandler pih = new ProxyInvocationHandler();pih.setTarget(userService);UserService proxy = (UserService) pih.getProxy();proxy.add();} }
-
相关文章:
Spring 学习(六)代理模式
10. 代理模式 案例 10.1 静态代理 角色分析 抽象角色:一般使用接口或者抽象类实现。真实角色:被代理的角色。代理角色:代理真实角色,含附属操作。客户:访问代理对象的角色。 租房案例 定义租赁接口 /*** TODO* 租房*…...
Educational Codeforces Round 155 (Rated for Div. 2) - D Sum of XOR Functions
学到的几个知识点: 1.拆位 对于整体上的异或操作可以转化为31个二进制位上的操作,每一位再上 。 将一次操作拆为31次来方便操作。 2. s[i]表示异或前缀和,l~r间的异或和为s[r] ^ s[l - 1] ----> 拆完位后这个公式还能再推出一个性…...
[C++ 网络协议] I/O流分离所带来的半关闭问题
1.问题和解决方法 根据所学内容,I/O流分离现如今有如下2种方法: 1.调用进程fork函数,分离出子进程,主进程和子进程分别进行输入流的读和输出流的写。 2.用FILE指针按读模式和写模式将输入流和输出流进行区分。 第一种方法&#…...
根据文章段落内容自动插入图片php版
每篇内容根据段落判断插入图片代码附上: $chatd"<table>";if(stripos($content,$chatd)0){//随机输出三张图功能if($moduleid!37 &&$thumb){//判断是否存在图$idrand(1,999999);$midrand(1,9999999);$getimg"http://www.nongpin88.co…...
在GEHC的第一个sprint记录
今天是进入GEHC XR ATX的第25天,是周日,下周二我的第一个sprint也就到期了,幸好在这周五晚上完成了,当然还差个分享。在此记录第一个sprint中两个story过程。 第一个story是操作固定式DR设备进行exposure整个过程。这是所有新人必…...
MFC 绘图
效果图:三张bmp图 字 竖线 组成 在OnPaint()函数中 CPaintDC dc(this);CRect rect;GetClientRect(&rect); //获取客户区矩形CDC dcBmp; //定义并创建一个内存设备环境dcBmp.CreateCompatibleDC(&dc); //创建兼容性DCCBitmap …...
算法 用两个栈实现队列-(栈+队列)
牛客网: BM42 题目: 用两个栈模拟队列 思路: stack1, stack2两个栈,入队只选择stack1, 出队只选择stack2, 如果stack2为空,将stack1元素全部出栈并入栈stack2。 代码: // gopackage mainvar stack1 [] int var stack2 [] intfunc Push(node int) {st…...
Android单编模块报FAILED: ninja: unknown target ‘MODULES-IN-vendor错误解决
有时我们需要单编Android AOSP一个APK或库文件或二进制,用来调试。 但可能这个模块本身是不参与系统整编编译的。我们在使用mmm或mm单独编译时就会报这个错误。 在检查Android.mk或Android.bp无误后,就要怀疑是不是这个目录的上级目录是不是没有包含这…...
地球的某一片红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——旅行季许少辉八月新书辉少许想象和世界一样宽广
地球的某一片红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——旅行季许少辉八月新书辉少许想象和世界一样宽广 地球的某一片红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——旅行季许少辉八月新书辉少许想象和世界一样宽广]...
Zookeeper-命令操作
命令操作 命令操作1) Zookeeper 数据模型2) Zookeeper 服务端常用命令3) Zookeeper 客户端常用命令 命令操作 1) Zookeeper 数据模型 ZooKeeper 是一个树形目录服务,其数据模型和Unix的文件系统目录树很类似,拥有一个层次化结构。 这里面的每一个节点都被称为&am…...
eclipse 添加注释
在 Eclipse 中,你可以使用注释来为你的代码添加说明、文档或标记。以下是如何在 Eclipse 中添加注释的一些方法: 单行注释:你可以使用单行注释来注释一行代码。在要注释的代码行前面添加双斜杠 // 即可。例如: // 这是一个单行注…...
Linux网络编程- 网络字节顺序
基本概念 网络字节顺序是一种规定的数据表示格式,被用于TCP/IP协议栈,特别是在网络传输数据时。它确保不同的计算机和架构之间可以无缝地通信。网络字节顺序是大端字节序(big-endian)。 字节序的背景 计算机存储多字节数据&…...
如何永久关闭WPS任务窗口?
1、按住任务窗口上的浮动按钮,将其拖出来成悬浮窗口。 第二步,使用火绒弹窗拦截,选中弹出的窗口,进行拦截。注意:拦截次数为2次。即进行2次操作。 操作两次后,弹窗被拦截,此时Word文档改为双页显…...
Cesium 问题:加载 geojson 数据量大浏览器会崩,使用primitive方式加载
文章目录 问题分析 问题 之前加载geojson数据都是使用dataSource和entity的方式,但是当数据量大时,浏览器就会崩掉:提示浏览器内存不足,已暂停渲染 分析 使用primitive方式加载数据,可以提高加载渲染效率。实现方法…...
C++ Primer----1.5类简介 章节练习
头文件 Sales_item.h #ifndef SALESITEM_H #define SALESITEM_H #include <iostream> #include <string>class Sales_item{ public:Sales_item(const std::string &book):isbn(book),units_sold(0),revenue(0.0){}Sales_item(std::istream &is){ is >&…...
爬楼梯Java(斐波那契数列)
题目:有n阶楼梯,一次只能爬一层或者两层,请问有多少种方法? 这类题目其实都可以用斐波那契数列来解决,比如: 一阶楼梯只有一种方法 二阶楼梯有(11,2)两种方法 三阶楼梯有(111,12,21)三种方法 四阶楼梯有(1111,121,112,22,211)五种方式 五阶楼梯有(11111,1112,122,1211,1…...
Maven项目package为jar包后在window运行报A JNI error has occurred
原因:本地java版本与项目结构中使用的java版本不一致(之前因为别的需求把idea的java版本改为了18) 解决方法 打开项目结构,将idea的java版本改为与本地一致 再修改项目中的pom.xml 重新编译,package即可...
iview 的table表格组件使单元格可编辑和输入
表格的列定义中,在需要编辑的字段下使用render函数 template表格组件 <Table border :data"data" :columns"tableColumns" :loading"loading"></Table>data中定义table对象 table: {tableColumns: [{title: 商品序号,k…...
统计的基本概念及抽样分布
文章目录 🍋引言🍋总体(Population)🍋总体参数 🍋样本(Sample)🍋随机样本🍋样本统计量 🍋统计量(Statistic)🍋…...
【C++】class的设计与使用(四)this指针
this指针 this作用域是在类内部,只能在成员函数中使用;this在成员函数的开始前构造,在成员函数的结束后清除;编译器在编译的时候也会自动加上this,它作为非静态成员函数的隐含形参,对各成员的访问均通过th…...
ollama部署本地大模型|translategemma-4b-it效果对比:vs NLLB-3B、vs SeamlessM4T-v2
ollama部署本地大模型|translategemma-4b-it效果对比:vs NLLB-3B、vs SeamlessM4T-v2 想在自己电脑上跑一个翻译模型,但又担心模型太大、速度太慢?今天我们来聊聊一个轻量级的新选择——Google推出的TranslateGemma-4b-it。更重要…...
DeepSeek技术解析:如何利用128K上下文窗口提升代码生成效率
1. 128K上下文窗口的技术革命 第一次看到DeepSeek支持128K上下文窗口时,我的反应和大多数开发者一样:"这数字是不是多打了个0?"毕竟在主流大模型还停留在32K上下文的时候,这个参数直接翻了四倍。但实测下来才发现&#…...
C#实战:5分钟搞定Modbus RTU通讯(基于NModbus4库)
C#实战:5分钟搞定Modbus RTU通讯(基于NModbus4库) 工业自动化领域的数据采集离不开设备通讯协议的支持,而Modbus RTU作为最广泛应用的串行通信协议之一,几乎成为工控开发者的必修课。今天我们就用C#和NModbus4库&#…...
泛微E9 OA流程表单右上角加按钮?用Ecode 5分钟搞定(附完整代码)
泛微E9流程表单5分钟极速加装功能按钮实战指南 每次接到"明天就要上线"的需求时,IT部门的咖啡机总是格外忙碌。上周三下午4点,我正收拾背包准备下班,业务部门的小王火急火燎地冲进办公室:"老师!采购流程…...
探索含简易撬棒电路crowbar的双馈风机Simulink仿真模型
【含有简易撬棒电路crowbar的双馈风机simulink仿真模型】 含过电压保护电路的双馈风机模型。 此模型中的撬棍(crowbar)不是使用 IGBT 或理想开关构建的。 通过改变转子侧变换器的参考电压,对撬棒电路的切入和切出进行建模。 控制策略是最常见…...
RK3588部署MMPose模型踩坑实录:手把手教你解决ReduceL2算子溢出与精度丢失问题
RK3588部署MMPose模型实战:ReduceL2算子溢出问题的深度解析与手术级修复 当关键点检测模型的精度要求遇上边缘计算设备的硬件限制,RK3588平台上的MMPose部署往往会遭遇令人头疼的算子兼容性问题。其中ReduceL2算子的溢出问题尤为典型——它像一道无形的屏…...
OpenClaw+nanobot科研利器:自动抓取论文并生成综述
OpenClawnanobot科研利器:自动抓取论文并生成综述 1. 为什么需要自动化文献综述工具 作为一名经常需要跟踪前沿研究的科研工作者,我深刻体会到手动整理文献的痛苦。每次开题或写综述时,需要花费大量时间在arXiv、PubMed等平台反复搜索、下载…...
前端国际化:别让你的应用只懂一种语言
前端国际化:别让你的应用只懂一种语言 毒舌时刻这应用写得跟方言似的,出了本地就没人懂。各位前端同行,咱们今天聊聊前端国际化。别告诉我你的应用还只有中文版本,那感觉就像在国际会议上只说方言——能说,但没人懂。 …...
海尔智能家居无缝接入HomeAssistant:打破品牌壁垒的终极指南
海尔智能家居无缝接入HomeAssistant:打破品牌壁垒的终极指南 【免费下载链接】haier 项目地址: https://gitcode.com/gh_mirrors/ha/haier 还在为家中海尔设备无法与其他智能设备联动而烦恼吗?想象一下,炎热的夏天回家前就能远程开启…...
别再手动装Office了!用Docker和LinuxServer.io镜像,5分钟搞定LibreOffice在线办公环境
5分钟极速部署:用Docker打造即开即用的LibreOffice云办公环境 你是否经历过这样的崩溃时刻?临时需要处理一份文档,却发现系统里的办公软件版本老旧、字体缺失;或是刚重装系统,又要花半小时等待Office安装进度条爬完。更…...
