设计模式--代理模式
笔记来源:尚硅谷Java设计模式(图解+框架源码剖析)
代理模式
1、代理模式的基本介绍
- 1)代理模式:为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象
- 2)这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能
- 3)被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象
- 4)代理模式有不同的形式,主要有三种:
- 静态代理
- 动态代理:JDK 代理、接口代理
- Cglib 代理:可以在内存动态的创建对象,而不需要实现接口,它是属于动态代理的范畴
2、静态代理
2.1、基本介绍
静态代理在使里时,需要定义接口或者父类,被代理对象(即目标对象)与代理对象一起实现租同的接口或者是继承和同父类—
应用实例
2.2、应用实例
- 1)定义一个接口:
ITeacherDao
- 2)目标对象
TeacherDAO
实现接口ITeacherDAO
- 3)使用静态代理方式,就需要在代理对象
TeacherDAOProxy
中也实现ITeacherDAO
- 4)调用的时候通过调用代理对象的方法来调用目标对象
- 5)特别提醒:代理对象与目标对象要实现相同的接口,然后通过调用相同的方法来调用目标对象的方法
UML 类图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GzKBb7vY-1693135171412)(https://s2.loli.net/2021/12/08/k4aXGKCedrq3sO6.png)]
核心代码
/*** 代理接口*/
public interface ITeacherDao {void teach();
}
/*** 被代理对象*/
public class TeacherDao implements ITeacherDao {@Overridepublic void teach() {System.out.println("老师授课中...");}
}
/*** 代理对象*/
public class TeacherDaoProxy implements ITeacherDao {private ITeacherDao iTeacherDao;public TeacherDaoProxy(ITeacherDao iTeacherDao) {this.iTeacherDao = iTeacherDao;}@Overridepublic void teach() {System.out.println("准备授课...");iTeacherDao.teach();System.out.println("结束授课...");}
}
调用代理
//创建被代理对象
TeacherDao teacherDao = new TeacherDao();
//创建代理对象,聚合被代理对象
TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
//通过代理对象,调用被代理对象的方法
teacherDaoProxy.teach();
2.3、静态代理优缺点
- 1)优点:在不修改目标对象的功能前提下,能通过代理对象对目标功能扩展
- 2)缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类
- 3)缺点:一旦接口增加方法,目标对象与代理对象都要维护
3、动态代理
3.1、基本介绍
- 1)代理对象不需要实现接口,但是目标对象要实现接口,否则不能用动态代理
- 2)代理对象的生成,是利用 JDK 的 APl,动态的在内存中构建代理对象
- 3)动态代理也叫做:JDK 代理、接口代理
3.2、JDK 中生成代理对象的 API
-
1)代理类所在包:
java.lang.reflect.Proxy
-
2)JDK 实现代理只需要使用
newProxyInstance
方法,但是该方法需要接收三个参数,完整的写法是:static Object newProxylnstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
UML 类图
核心代码
// ITeacherDao与TeacherDao同上
/*** 代理工厂*/
public class TeacherFactory {/*** 目标对象*/private Object target;public TeacherFactory(Object target) {this.target = target;}public Object newProxyInstance() {return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("JDK代理授课开始...");Object returnVal = method.invoke(target, args);System.out.println("JDK代理授课结束...");return returnVal;}});}
}
其中几个参数
- 1)
ClassLoader loader
:指定当前目标对象使用的类加载器,获取加载器的方法固定 - 2)
Class<?>[] interfaces
:目标对象实现的接口类型,使用泛型方法确认类型 - 3)
InvocationHandler h
:事情处理,执行目标对象的方法时触发事情处理器方法,把当前执行的目标对象方法作为参数传入
4、Cglib 代理
4.1、基本介绍
- 1)静态代理和 JDK 代理模式都要求目标对象是实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理——这就是 Cglib 代理
- 2)Cglib 代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展,有些书也将 Cglib 代理归属到动态代理。
- 3)Cglib 是一个强大的高性能的代码生成包,它可以在运行期扩展 java 类与实现 java 接口。它广泛的被许多 AOP 的框架使用,例如 Spring AOP,实现方法拦截
- 4)在 AOP 编程中如何选择代理模式:
- 目标对象需要实现接口,用 JDK 代理
- 目标对象不需要实现接口,用 Cglib 代理
- 5)Cglib 包的底层是通过使用字节码处理框架 ASM 来转换字节码并生成新的类
4.2、实现步骤
-
1)需要引入
cglib
的 jar 文件 -
2)在内存中动态构建子类,注意代理的类不能为
final
,否则报错java.lang.IllegalArgumentException
-
3)目标对象的方法如果为
final
/static
,那么就不会被拦截,即不会执行目标对象额外的业务方法
4.3、应用实例
UML 类图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Z7FIdMT-1693135171413)(https://s2.loli.net/2021/12/10/jMtwO2nBWPRurlh.png)]
核心代码
/*** 被代理对象*/
public class TeacherDao {public String teach() {System.out.println("老师授课中...");return "Good";}
}/*** 代理工厂类*/
public class ProxyFactory implements MethodInterceptor {/*** 目标对象*/private Object target;/*** 构造函数** @param target*/public ProxyFactory(Object target) {this.target = target;}/*** 返回代理对象** @return*/public Object getProxyInstance() {// 1、创建工具类Enhancer enhancer = new Enhancer();// 2、设置父类enhancer.setSuperclass(target.getClass());// 3、设置回调函数enhancer.setCallback(this);// 4、创建子类对象,即代理对象return enhancer.create();}@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {System.out.println("cglib代理开始...");Object retVal = method.invoke(target, args);System.out.println("cglib代理结束...");return retVal;}
}
调用代理
//创建目标对象
TeacherDao teacherDao = new TeacherDao();
//通过代理工厂创建代理对象
TeacherDao proxyInstance = (TeacherDao) new ProxyFactory(teacherDao).getProxyInstance();
//通过代理对象调用目标对象方法
String retVal = proxyInstance.teach();
System.out.println("retVal=" + retVal);
5、代理模式的变体
几种常见的代理模式介绍一几种变体
-
1)防火墙代理:内网通过代理穿透防火墙,实现对公网的访问
-
2)缓存代理:比如:当请求图片文件等资源时,先到缓存代理取,如果取到资源则 ok;如果取不到资源,再到公网或者数据库取,然后缓存
-
3)远程代理:远程对象的本地代表,通过它可以把远程对象当本地对象来调用。远程代理通过网络和真正的远程对象沟通信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wq6cQidA-1693135171413)(https://s2.loli.net/2021/12/11/TEyYHr7ZoB3KcjS.png)]
-
4)同步代理:主要使用在多线程编程中,完成多线程间同步工作
相关文章:

设计模式--代理模式
笔记来源:尚硅谷Java设计模式(图解框架源码剖析) 代理模式 1、代理模式的基本介绍 1)代理模式:为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象2)这样做的好处是…...

链路聚合原理
文章目录 一、定义二、功能三、负载分担四、分类五、常用命令 首先可以看下思维导图,以便更好的理解接下来的内容。 一、定义 在网络中,端口聚合是一种将连接到同一台交换机的多个物理端口捆绑在一起,形成一个逻辑端口的技术。通过端口聚合&…...

el-table表尾添加合计行,自动合计,且特殊列自定义计算展示
效果如图 1.element-ui的table表格有合计功能,但是功能却不完善,会有不显示和计算出现错误的问题,项目中有遇到,所以记录下 show-summary:自动合计 getSummaries():对合计行进行特…...

uview ui 1.x ActonSheet项太多,设置滚动(亲测有效)
问题:ActionSheet滚动不了。 使用uview ui :u-action-sheet, 但是item太多,超出屏幕了, 查了一下文档,并没有设置滚动的地方。 官方文档:ActionSheet 操作菜单 | uView - 多平台快速开发的UI框架 - uni-a…...

STM32 Cubemx 同名外设中断及回调
文章目录 前言示例工程个人理解 前言 最近在学习STM32,采用HAL库开发方式。记录一下同名外设中断及回调。 这里提及的同名外设指USART1/2之类的相同外设,但不是同一个instance。 示例工程 以使用cubemx配置两个同名外设EXTI0/EXT4为例。 在NVIC配置…...

储能辅助电力系统调峰的容量需求研究(matlab代码)
目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序参考文献《储能辅助电力系统调峰的容量需求研究》,是一个很常规很经典的matlab优化代码,主要是对火电、风电和储能等电力设备主体进行优化调度,在调峰能力达不到时采…...

非计算机科班如何丝滑转码?(本人就是有点不丝滑)
我觉得无非三个办法可以选择(当然可能有其他方法) 自学 报班 有师傅带 但是在学习之前,你一定要明确你学习编程的目的是什么! 游戏开发?后台研发?爬虫工程师?前端程序员?数据分析师? 或者 仅仅是想做一…...

tensorrtx部署yolov5 6.0
文章目录 一. yolov5 v6.0训练模型二.训练好的yolov5模型转tensorrt引擎 一. yolov5 v6.0训练模型 官网下载yolov5 v6.0代码 下载官方预训练好的模型 安装yolov5所需要的库文件,requirements.txt在下载好的yolov5源代码中有 pip install -r C:\Users\10001540…...
用html5写一个音乐播放器
在HTML5中创建一个简单的音乐播放器时,你可以使用<audio>元素来实现。以下是一个基本的示例: html <!DOCTYPE html> <html> <head> <title>音乐播放器</title> </head> <body> <h1>音乐…...

postgresql类型转换函数
postgresql类型转换函数 简介CAST 函数to_date 函数to_timestamp 函数to_char 函数to_number 函数隐式类型转换 简介 类型转换函数用于将数据从一种类型转换为另一种类型。 CAST 函数 CAST ( expr AS data_type )函数用于将 expr 转换为 data_type 数据类型;Post…...
Go 自学:Array阵列
以下代码展示了用两种方法建立array。 package mainimport "fmt"func main() {var fruitList [4]stringfruitList[0] "Apple"fruitList[1] "Tomato"fruitList[3] "Peach"fmt.Println("Fruit list is: ", fruitList)fmt.…...

大数据平台与数据仓库的五大区别
随着大数据的快速发展,很多人难以区分大数据平台与数据仓库的区别,两者傻傻分不清楚。今天我们小编就给大家汇总了大数据平台与数据仓库的五大区别,希望有用哦!仅供参考! 大数据平台与数据仓库的五大区别 一、概念不同…...
React 钩子汇总
React 钩子 一、常用的 React 钩子: 1. useState 用于在函数式组件中添加状态管理。它返回一个状态值和一个更新状态的函数,让你可以在组件中追踪和更新状态。 2. useEffect 用于在组件渲染完成后执行副作用操作,比如数据获取、订阅等。…...
Python爬取旅游网站数据机票酒店价格对比分析
本文将介绍如何使用Python爬虫从旅游网站上获取机票和酒店的价格数据,并实现价格对比分析,帮助你做出明智的旅行决策。我们提供了完善的方案和代码,让你能够轻松操作并获得实际价值。 使用Python爬虫获取旅游网站上的机票和酒店价格数据&…...

OA项目之会议通知(查询是否参会反馈详情)
目录 会议查询 是否参会 反馈详情 讲解思路 会议通知SQL语句分析 反馈详情SQL语句分析 后台代码编写 前端代码编写 效果预览 会议查询 MeetingFeedBack.java package com.zking.oa.model;import org.lisen.mvc.util.AutoIncrement; import org.lisen.mvc.util.…...
如何维护自己的电脑的措施
维护自己的电脑可以采取以下措施: 硬件维护:定期清理电脑表面的灰尘和污垢,避免灰尘对电脑内部部件造成影响。电源插座要保持接触良好,保证电脑的电源稳定。如果使用笔记本电脑,要注意保证散热通畅,避免电…...

VS2022 Community 安装步骤
VS2022 Community 安装步骤(C语言学习) 1. 下载地址2. 安装步骤 1. 下载地址 链接: VS2022 Community下载地址 2. 安装步骤 双击图标进行安装。 点击【继续】后等待安装。 选择需要的安装包并修改安装位置,然后点击【安装】。 点击安装…...
vue3中mitt.js使用
在vue2中我们通过事件总线eventbus,来实现两个平行组件之间的通信: bus.js import Vue from vue // 创建vue实例 const Bus new Vue() export default Bus在具体的组件中: A.vue import Bus from ./bus.js // 发布一个事件 Bus.$emit(sendData, {nam…...
Redis 内存淘汰策略详解
Redis 内存淘汰策略详解 一、简介Redis内存管理问题 二、内存淘汰策略1.为什么需要内存淘汰策略2.内存淘汰策略分类(1)noeviction(2)allkeys-lru(3)allkeys-lfu(4)volatile-lru&…...

初识Redis之分布式
一.简单介绍: Redis是用来在内存中, 存储数据的, 他的初心是用来搞消息中间件(或者说消息队列 很熟悉了吧~~),但是呢用的不多,他现在主要是用来做 数据库,缓存 用来存储数据, 为什么不直接存储呢? Redis的优势就在于分布式系统 二.分布式系统 要说其分布式系统,简单想想都能…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...