【设计模式】代理模式(结构型)⭐⭐⭐

文章目录

  • 1.概念
    • 1.1 什么是代理模式
    • 1.2 优点与缺点
  • 2.实现方式
    • 2.1 静态代理
    • 2.2 动态代理
  • 3. Java 哪些地方用到了代理模式
  • 4. Spring 哪些地方用到了代理模式

1.概念

1.1 什么是代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,它允许通过一个代理对象来控制对另一个对象的访问。

1.2 优点与缺点

优点:
1.可以控制对真实对象的访问。
2.可以延迟真实对象的创建,减少系统开销。
3.可以提供额外的服务,如缓存、权限检查等。
缺点:
1.增加了系统的复杂性,因为引入了额外的代理类。
2.可能会降低系统的性能,因为代理会增加一层间接调用。

2.实现方式

2.1 静态代理

// Image接口
public interface Image {void display();
}// RealImage类,实现了Image接口
public class RealImage implements Image {private String fileName;// 构造函数,加载图像public RealImage(String fileName) {this.fileName = fileName;loadImageFromDisk();}// 加载图像的模拟方法private void loadImageFromDisk() {System.out.println("Loading  " + fileName);}// 显示图像@Overridepublic void display() {System.out.println("Displaying " + fileName);}
}// Image代理类
public class ImageProxy implements Image {private String fileName;private Image realImage;// 构造函数public ImageProxy(String fileName) {this.fileName = fileName;}// 显示图像,如果真实图像尚未加载,则先加载@Overridepublic void display() {if (realImage == null) {realImage = new RealImage(fileName);}realImage.display();}
}// 测试类
public class ProxyPatternDemo {public static void main(String[] args) {Image image = new ImageProxy("test_10mb.jpg");// 图像将从磁盘加载image.display();System.out.println("");// 图像不需要从磁盘加载image.display();}
}

2.2 动态代理

动态代理通常使用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来实现。

// Image接口
public interface Image {void display();
}// RealImage类,实现了Image接口
public class RealImage implements Image {private String fileName;// 构造函数,加载图像public RealImage(String fileName) {this.fileName = fileName;loadImageFromDisk();}// 加载图像的模拟方法private void loadImageFromDisk() {System.out.println("Loading  " + fileName);}// 显示图像@Overridepublic void display() {System.out.println("Displaying " + fileName);}
}// 动态代理类
public class DynamicImageProxy {public static Image newInstance(String fileName) {return (Image) java.lang.reflect.Proxy.newProxyInstance(Image.class.getClassLoader(),new Class[]{Image.class},new java.lang.reflect.InvocationHandler() {private Image realImage = null;@Overridepublic Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable {if (realImage == null) {realImage = new RealImage(fileName);}return method.invoke(realImage, args);}});}
}// 测试类
public class ProxyPatternDemo {public static void main(String[] args) {Image image = DynamicImageProxy.newInstance("test_10mb.jpg");// 图像将从磁盘加载image.display();System.out.println("");// 图像不需要从磁盘加载image.display();}
}

3. Java 哪些地方用到了代理模式

RMI(Remote Method Invocation): Java的RMI机制使用代理模式来实现远程对象的透明访问。RMI系统提供的代理类将远程方法调用转换为对远程对象的调用。
JDBC(Java Database Connectivity): JDBC驱动程序管理器使用代理模式来加载和实例化JDBC驱动程序。当应用程序请求连接到数据库时,代理会加载适当的驱动程序并建立连接。
动态代理: Java的动态代理机制允许在运行时创建代理类和代理实例。这通常用于AOP(面向切面编程)框架,如Spring AOP,其中代理用于在目标对象的方法调用前后执行增强代码。
事件监听器: 在Swing或其他GUI框架中,事件监听器使用代理模式来处理事件。事件源将事件委托给事件监听器,后者作为事件处理的代理。
延迟加载: 在Hibernate或其他ORM框架中,代理模式用于实现延迟加载。代理对象代表真实对象,并在真正需要访问对象数据时才加载数据。
保护代理: 在需要控制对资源的访问时,可以使用保护代理来检查调用者的权限,并根据权限决定是否允许访问资源。
智能引用: 在需要跟踪对象的使用情况时,可以使用智能代理来记录对象的使用次数、最后使用时间等信息。

4. Spring 哪些地方用到了代理模式

AOP(面向切面编程): Spring AOP使用代理模式来实现方法拦截。Spring的AopProxy类充当代理,它根据配置创建代理对象,并在目标对象的方法调用前后执行增强代码。
事务管理: Spring的事务管理器使用代理模式来管理事务。TransactionInterceptor类充当代理,它在目标方法执行前后管理事务的开启、提交或回滚。
事件发布: Spring的事件驱动模型使用代理模式来解耦事件的生产者和消费者。ApplicationEventMulticaster类充当代理,它将事件发布给所有注册的监听器。
Web集成: Spring的Web模块使用代理模式来集成不同的Web框架。例如,DispatcherServlet充当代理,它将HTTP请求转换为Spring MVC框架的调用。
资源访问: Spring的ResourceLoader和Resource接口使用代理模式来抽象不同类型的资源访问。ResourceLoader的实现类充当代理,它们将资源访问的调用转换为具体文件系统、类路径或URL的访问。
消息服务: Spring的JMS(Java消息服务)集成使用代理模式来适配不同的消息中间件。JmsTemplate和JmsListenerContainerFactory类充当代理,它们将Spring的消息抽象转换为具体的消息中间件操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/22932.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

带你认识ffmpeg

FFmpeg是一个开源的跨平台音视频处理工具集,它提供了丰富的音视频处理功能和库,被广泛应用于音视频编解码、格式转换、流媒体处理等领域。 应用场景: 视频编解码:FFmpeg可以对各种视频格式进行编解码,包括但不限于AV…

类的特殊成员函数

使用类的嵌套&#xff0c;并自定义析构函数 #include <iostream>using namespace std; class Per{ private:string name;int age;double hight;double weight; public:Per(string name,int age,double hight,double weight):name(name),age(age),hight(hight),weight(we…

图片如何修改尺寸?四种好用的修改图片尺寸方法!

图片如何修改尺寸&#xff1f;图片是一种常见的文件类型&#xff0c;它存在于什么生活的方方面面&#xff0c;虽然图片很好用&#xff0c;但是大家日常也要注意图片的尺寸&#xff0c;如果图片尺寸不对是会带来很多问题的&#xff0c;下面小编就举例说明几个问题&#xff0c;首…

web 前端技术的一些知识点分享~

css的规则是由选择器和 组成的 目录 css的规则是由选择器和 组成的 CSS&#xff08;层叠样式表&#xff09;的规则是由选择器和声明块组成的。 选择器用于选定页面上的元素&#xff0c;这可以是一个元素标签&#xff08;如 h1&#xff09;、类&#xff08;如 .classname…

Unity 自定义房间布局系统 设计与实现一个灵活的房间放置系统 ——物体占用的区域及放置点自动化

放置物体功能 效果&#xff1a; 功能&#xff1a; 自定义物体占用区域的大小一键调整占用区域调整旋转度数&#xff0c;分四个挡位&#xff1a; NoRotation&#xff1a;该物体不能调整旋转。MaximumAngle&#xff1a;每次转动90。NormalAngle&#xff1a;每次转动45&#xff…

根据租户id切换数据源

花了半天时间&#xff0c;使用spring-boot实现动态数据源&#xff0c;切换自如 在一个项目中使用多个数据源的情况很多&#xff0c;所以动态切换数据源是项目中标配的功能&#xff0c;当然网上有相关的依赖可以使用&#xff0c;比如动态数据源&#xff0c;其依赖为&#xff0c;…

银河麒麟解压命令

银河麒麟&#xff08;Kylin&#xff09;操作系统是基于Linux的操作系统分支之一&#xff0c;其使用的解压命令与Linux系统中的命令基本相同。 在银河麒麟系统中&#xff0c;常用的解压命令有以下几种&#xff1a; 对于.tar文件&#xff1a; tar -xvf file.tar对于.tar.gz或.…

探索营销系统业务架构的设计与应用

随着市场竞争的日益激烈和消费者需求的不断变化&#xff0c;营销系统作为企业营销管理的重要组成部分&#xff0c;扮演着至关重要的角色。本文将深入探讨营销系统业务架构的设计与应用&#xff0c;从客户关系管理、营销活动管理、数据分析和智能化服务等方面进行全面解析&#…

Innodb Buffer Pool缓存机制(四)预读与Mysql改进的LRU策略

一、什么是预读 InnoDB提供了预读(read ahead)。所谓预读&#xff0c;就是InnoDB认为执行当前的请求可能之后会读取某些页面&#xff0c;就预先把它们加载到Buffer Pool中。根据触发方式的不同&#xff0c;预读又可以细分为下边两种&#xff1a; 1.1 线性预读 InnoDB提供了一…

掘金AI商战宝典-高阶班:如何用AI制作视频(11节视频课)

课程下载&#xff1a;掘金AI商战宝典-高阶班&#xff1a;如何用AI制作视频(11节视频课)-课程网盘链接提取码下载.txt资源-CSDN文库 更多资源下载&#xff1a;关注我。 课程目录&#xff1a; 1-第一讲用AI自动做视频(上)_1.mp4 2-第二讲用AI自动做视频(中)_1.mp4 3-第四讲A…

U9C的数据查询视图Sql

U9C的数据查询视图Sql if object_id(TEMPDB..#priceTable) is not null begin drop table #priceTable endcreate table #priceTable (polineCreatedOn date,price varchar(max),itemid varchar(max),purchaseOrderdocno varchar(max),)insert into #priceTable select max(…

阿里云邮件推送服务配置教程:怎么做批发?

阿里云邮件推送的API配置步骤&#xff1f;配置教程有哪些步骤&#xff1f; 阿里云邮件推送服务凭借其高并发、稳定性强和安全性高等特点&#xff0c;成为众多企业的首选。Aok将详细介绍如何使用阿里云邮件推送服务进行批发配置&#xff0c;并简要提及AokSend的优势。 阿里云邮…

UE4_环境_材质函数

学习笔记&#xff0c;不喜勿喷&#xff0c;欢迎指正&#xff0c;侵权立删&#xff01; 1、建立材质函数Distance_Fun&#xff0c;勾选公开到库。 2、添加函数输入节点FunctionInput&#xff0c; 这个输入我们想作为混合材质属性BlendMaterialAttributes的alpha输入节点&#x…

022、键管理_遍历键

Redis提供了两个命令遍历所有的键,分别是keys和scan 1.全量遍历键 keys patternkeys命令是支持pattern匹配的 127.0.0.1:6379> dbsize (integer) 0 127.0.0.1:6379> mset hello world redis best jedis best hill high OK如果要获取所有的键,可以使用keys pattern命…

手撸 串口交互命令行 及 AT应用层协议解析框架

在嵌入式系统开发中&#xff0c;命令行接口&#xff08;CLI&#xff09;和AT命令解析是常见的需求。CLI提供了方便的调试接口&#xff0c;而AT命令则常用于模块间的通信控制。本文将介绍如何手动实现一个串口交互的命令行及AT应用层协议解析框架&#xff0c;适用于FreeRTOS系统…

06Docker-Compose和微服务部署

Docker-Compose 概述 Docker Compose通过一个单独的docker-compose.yml模板文件来定义一组相关联的应用容器&#xff0c;帮助我们实现多个相互关联的Docker容器的快速部署 一般一个docker-compose.yml对应完整的项目,项目中的服务和中间件对应不同的容器 Compose文件实质就…

锂电池寿命预测 | Matlab基于SSA-SVR麻雀优化支持向量回归的锂离子电池剩余寿命预测

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 【锂电池剩余寿命RUL预测案例】 锂电池寿命预测 | Matlab基于SSA-SVR麻雀优化支持向量回归的锂离子电池剩余寿命预测&#xff08;完整源码和数据&#xff09; 1、提取NASA数据集的电池容量&#xff0c;以历史容量作…

【C++课程学习】:类和对象(上)(类的基础详细讲解)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f35f;1.1类的引出&#xff1a; &#x1f35f;1.2类的结构&#xff1a; &#x1f35f;1.3类的…

LeetCode-82. 删除排序链表中的重复元素 II【链表 双指针】

LeetCode-82. 删除排序链表中的重复元素 II【链表 双指针】 题目描述&#xff1a;解题思路一&#xff1a;用一个cur即可实现去重cur.next cur.next.next背诵版&#xff1a;解题思路三&#xff1a;0 题目描述&#xff1a; 给定一个已排序的链表的头 head &#xff0c; 删除原始…

【java前端课堂】02_类和方法的定义区别

目录 简介&#xff1a; 类 方法 类和方法之间的主要区别如下&#xff1a; 定义与结构&#xff1a; 实例化&#xff1a; 作用范围&#xff1a; 生命周期&#xff1a; 下面是一个简单的Java类和方法示例&#xff1a; 简介&#xff1a; 类 在Java&#xff08;以及许多其他面向…