【设计模式--结构型--代理模式】

设计模式--结构型--代理模式

    • 代理模式
      • 概述
      • 结构
      • 静态代理案例:卖车票
      • jdk动态代理
      • cglib代理
      • 三种代理对比
      • 优缺点
      • 使用场景

代理模式

概述

由于某些原因需要给某对象提供一个代理以控制该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
java中的代理机制分为静态代理和动态代理

  • 静态代理:代理类在在编译期就生成
  • 动态代理:代理类在java运行时动态生成。
    • JDK代理
    • CGLib代理

结构

代理模式分为三种角色:

  • 抽象主题类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
  • 真实主题类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  • 代理类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

静态代理案例:卖车票

市面上任何卖火车票软件都是通过12306来买的,这就是一个典型的代理模式,12306是目标对象,其他售票软件是代理对象。
在这里插入图片描述

public class ProxyPoint implements SellTicket{// 声明12306类对象private TrainStation trainStation = new TrainStation();@Overridepublic void sell() {System.out.println("其它app买票---可以增强");trainStation.sell();}
}
/*** 卖火车票的接口*/
public interface SellTicket {void sell();
}
public class TrainStation implements SellTicket{@Overridepublic void sell() {System.out.println("12306卖火车票");}
}
public class Test01 {public static void main(String[] args) {ProxyPoint proxyPoint = new ProxyPoint();proxyPoint.sell();}
}

从上面代码中可以看出测试类是直接访问ProxyPoint类对象,也就是说ProxyPoint作为目标访问对象和目标对象的中介,同时也对sell方法进行了增强。

jdk动态代理

接下来使用动态代理实现上面案例,java中提供了一个动态代理类Proxy,Proxy并不是我们上面说的代理对象类,
而是提供了一个创建代理对象的静态方法(newProxyInstance)来获取代理对象。

/*** 获取代理对象的工厂类* 代理类也实现了对应的接口*/
public class ProxyFactory {// 声明目标对象private TrainStation station = new TrainStation();public SellTicket getProxyObject(){/*** ClassLoader loader 类加载器,用于加载代理类。可以通过目标对象获取类加载器* Class<?>[] interfaces 代理类实现的接口的字节码对象* InvocationHandler h 代理对象的调用处理程序*/SellTicket proxyObject = (SellTicket) Proxy.newProxyInstance(station.getClass().getClassLoader(),station.getClass().getInterfaces(),/*** Object proxy:代理对象,和proxyObject对象是同一个对象* Method method:对接口中的方法进行封装的method对象* Object[] args:调用方法的实际参数* 返回值:方法的返回值*/new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//System.out.println("代售app---增强");// 执行目标对象的方法return method.invoke(station, args);}});return proxyObject;}
}
/*** 卖火车票的接口*/
public interface SellTicket {void sell();
}

cglib代理

/*** 代理对象工厂,用来获取代理对象*/
public class ProxyFactory implements MethodInterceptor {private TrainStation station = new TrainStation();public TrainStation getProxyObject(){// 创建Enhancer对象,类似jdk代理中的Proxy类Enhancer enhancer = new Enhancer();// 设置父类的字节码对象enhancer.setSuperclass(TrainStation.class);// 设置回调函数enhancer.setCallback(this);// 创建代理对象TrainStation proxyObject = (TrainStation) enhancer.create();return proxyObject;}@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("cglib代理");// 要调用目标对象的方法TrainStation invoke = (TrainStation) method.invoke(station, objects);return invoke;}
}
public class TrainStation {public void sell() {System.out.println("12306卖火车票");}
}
public class Test02 {public static void main(String[] args) {// 创建代理工厂对象ProxyFactory factory = new ProxyFactory();// 获取代理对象TrainStation proxyObject = factory.getProxyObject();// 调用代理对象中的sell方法proxyObject.sell();}
}

三种代理对比

  • jdk代理和cglib代理
    • 使用CGLib实现动态代理,cglib底层采用ASM字节码生产框架,使用字节码技术生成代理类,在jdk1.6之前比使用java反射效率要高。
      唯一需要注意的是:cglib不能对声明为final的类或方法进行代理,因为cglib原理是动态生成被代理的子类。

      在jdk1.8对jdk动态代理优化后,jdk代理效率高于cglib代理,如果有接口使用jdk代理,没有接口使用cglib代理。

  • 动态代理和静态代理
    • 动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法处理(InvocationHandler.invoke)。这样在接口
      方法数量比较多的时候,我们可以灵活处理,而不需要像静态代理那样每一个方法进行中转。
      如果接口增加一个方法,静态代理模式处理实现所有类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。而动态代理不会出现该问题

优缺点

  • 优点:
    • 代理模式在客户端与目标对象之间起到了一个中介作用和保护作用
    • 代理对象可以扩展目标对象的功能
    • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度
  • 缺点:
    • 增加了系统的复杂度

使用场景

  • 远程代理
    • 本地服务通过网络请求远程服务。为了实现本地到远程的通信,我们需要实现网络通信,处理其中可能的异常。为良好的代码设计和可维护性,
      我们将网络通信部分隐藏起来,只暴露给本地服务一个接口,通过该接口即可访问远程服务提供的功能,而不必过多关心通信部分的细节。
  • 防火墙代理
    • 将浏览器配置成使用代理功能时,防火墙就可以将浏览器的请求转给互联网;当互联网返回响应时,代理服务器再把他转给你的浏览器。
  • 保护代理
    • 控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。

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

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

相关文章

FFmepeg——视频处理工具安装以及简单命令学习。

FFmpeg 是一个免费、开源且高度可定制的多媒体处理工具&#xff0c;它是一个强大的跨平台框架&#xff0c;用于处理音频、视频、多媒体流和图像。FFmpeg 的主要功能包括解码、编码、转码、流处理、多路复用、分离、合并、过滤等&#xff0c;支持多种音视频格式&#xff0c;包括…

【精简】mysql创建自定义函数 sql写法举例

一&#xff0c;举例的sql是查询 某个时间点某个币种的汇率 create function get_rate(idate date,CURRENCY varchar(32)) returns decimal(21,6) begin declare res decimal(21,6) default 1;selec rate into resfromt_exchangerate tewhere ratedate idateand CURRENCYID C…

SQL进阶理论篇(十三):数据库的查询优化器是什么?

文章目录 简介什么是查询优化器查询优化器的两种优化方式总结参考文献 简介 事务可以让数据库在增删改查的过程中&#xff0c;保证数据的正确性和安全性&#xff0c;而索引可以帮数据库提升数据的查找效率。查询优化器&#xff0c;则是帮助我们获取更高的SQL查询性能。 本节我…

具有超低功耗性能的R7F102GAC3CSP、R7F102GAC2DSP、R7F102G6C3CSP RL78/G22微控制器 16-bit MCU

RL78/G22 简介&#xff1a; 除了具有低电流消耗&#xff08;CPU工作时&#xff1a;37.5μA/MHz&#xff1b;STOP时&#xff1a;200nA&#xff09;外&#xff0c;RL78/G22微控制器还配备了丰富的电容触摸通道。完备的16-48引脚封装和32KB-64KB闪存&#xff0c;扩充了新一代RL78…

Java如何开发PC客户端(Windows,Mac,Linux)

项目编译工具&#xff1a;Gradle开发工具&#xff1a; Idea开发语言&#xff1a; 建议java17以上ui组件&#xff1a;openjfx (org.openjfx.javafxplugin)打包工具: jpackage (org.beryx.jlink) 一、如何解决打包问题 java 14以后&#xff0c;有了jpackage工具&#xff0c;能够…

计算机网络 运输层上 | 运输层概述 UDP协议 端口 套接字

文章目录 1 运输层概述1.1 运输层存在的意义1.2 运输层协议概述1.3 主要端口号 2 运输层主要协议 UDP2.1 UDP的特点2.2 UDP首部格式2.3 UDP工作流 1 运输层概述 1.1 运输层存在的意义 之前我们讲网络层的时候&#xff0c;已经可以将信息从一个主机传递到另一个主机了。 那么…

校园圈子交友系统,APP小程序H5,三端源码交付,支持二开!实名认证,大V认证,地图找伴,二手平台!

校园圈子交友系统&#xff0c;是属于自主定义开发的系统&#xff0c;内容有很多&#xff0c;先截取一些给大家看看&#xff0c;让大家更多的了解本系统&#xff0c;然后再做评价&#xff01; 校园后端下载地址&#xff1a;校园圈子系统小程序&#xff0c;校园拼车&#xff0c;校…

XM平台官网开户注册流程图解

注册前准备 在进行XM外汇官网注册之前&#xff0c;首先需要准备必要的信息&#xff0c;包括个人身份信息、联系方式以及相关财务信息。确保这些信息的准确性是保证注册流程顺利进行的关键。 一、要访问XM外汇官方网站&#xff0c;首先打开您的浏览器。在浏览器的地址栏中输入…

数据分析基础之《numpy(6)—合并与分割》

了解即可&#xff0c;用panads 一、作用 实现数据的切分和合并&#xff0c;将数据进行切分合并处理 二、合并 1、numpy.hstack 水平拼接 # hstack 水平拼接 a np.array((1,2,3)) b np.array((2,3,4)) np.hstack((a, b))a np.array([[1], [2], [3]]) b np.array([[2], […

华为OS与麒麟OS:华为自研操作系统的对决

导言 在移动操作系统领域&#xff0c;华为OS和麒麟OS代表了华为在自主研发方面的努力。本文将深入探讨这两个操作系统的特点、竞争关系以及它们在用户体验、生态系统建设等方面的差异。 1. 背景与起源 华为OS的诞生&#xff1a; 华为OS是华为公司为应对外部环境而自主…

英国呼叫中心的功能

随着互联网的普及和信息技术的发展&#xff0c;越来越多的企业需要通过呼叫中心来管理客户关系和提供售后服务。英国作为主要的海外外贸市场之一&#xff0c;也是呼叫中心面向客户服务的重要国家。 英国呼叫中心的功能 英国呼叫中心的功能大致分为四类&#xff1a;接听电话、…

用户管理第2节课--idea 2023.2 后端--实现基本数据库操作(操作user表)

一、模型user对象>和数据库的字段关联 & 自动生成 【其中涉及删除表数据&#xff0c;一切又从零开始】 二、模型user对象>和数据库的字段关联 2.1在model文件夹下&#xff0c;新建 user对象 2.1.1 概念 大家可以想象我们现在的数据是存储在数据库里的&…

【Spring Security】打造安全无忧的Web应用--入门篇

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Spring Security的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Spring Security是什么 1.概…

Spring Boot3通过GraalVM生成exe执行文件

一、安装GraalVM 1、官网&#xff1a;https://www.graalvm.org/downloads/ 2、配置环境变量 2.1、环境变量必须使用JAVA_HOME&#xff0c;否则会出现问题 2.2、在系统变量配置Path,%JAVA_HOME%\bin&#xff0c;注意必须放在顶部第一位 2.3、配置jdk的环境变量&#xff0c;在P…

【Spring实战】创建第一个项目

文章目录 使用 Spring Initializr 创建第一个项目1. 打开官网2. 填写信息3. 生成工程4. 解压工程5. 导入 IDEA6. 编写 Hello world7. 启动项目8. 访问验证9. 详细代码最后 Spring 是一个强大且广泛使用的 Java 开发框架&#xff0c;提供了全面的基础设施和工具&#xff0c;用于…

如何将图片转为PDF

问题描述&#xff1a;如何将图片转为PDF&#xff0c;有时需要将纸质文档扫描成PDF&#xff0c;然后上传到网上。 解决办法&#xff1a;平时使用的方法是将图片插入到word文件中&#xff0c;然后将图片设置为浮于文字下方&#xff0c;然后调整图片的大小&#xff0c;铺满整个wo…

案例094:基于微信小程序的图书馆自习室座位预约管理系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

mysql:查看线程缓存中的线程数量

使用命令show global status like Threads_cached;可以查看线程缓存中的线程数量。 例如&#xff0c;查询线程缓存中的线程数量如下&#xff1a; 然后启动应用程序&#xff0c;使用连接&#xff0c;查询如下&#xff1a; 由查询结果可以看到&#xff0c;线程缓存中的线程数量…

2023_Spark_实验三十二:消费Kafka数据并保存到MySQL中

实验目的&#xff1a;掌握Scala开发工具消费Kafka数据&#xff0c;并将结果保存到关系型数据库中 实验方法&#xff1a;消费Kafka数据保存到MySQL中 实验步骤&#xff1a; 一、创建Job_ClickData_Process 代码如下&#xff1a; package examsimport org.apache.kafka.clien…

数据挖掘体系介绍

数据挖掘是什么&#xff1f; 简而言之&#xff0c;对数据进行挖掘&#xff0c;从中提取出有效的信息。一般我们会把这种信息通过概念、规则、规律、模式等有组织的方式展示出来&#xff0c;形成所谓的知识。特别是在这个大数据时代&#xff0c;当数据多到一定程度&#xff0c;…