代理模式Proxy

devtools/2024/12/22 9:04:52/
一、代理模式(Proxy)
1.代理模式的定义

代理模式给某一个对象提供一个代理对象,并由代理对象控制对真实对象的访问,起到对代理对象已有功能的增强

通俗的来讲代理模式就是我们生活中常见的中介。

2.作用
  • 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,

而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。

  • 开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理

类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。

3.代理模式的分类

我们有多种不同的方式来实现代理。如果按照代理创建的时期来进行分类的话可以分为两种:

  • 静态代理:

静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。在程序员运行之前,代理类.class文件就已经被创建了。

  • 动态代理:

动态代理是在程序运行时通过反射机制动态创建的。

    • 动态代理分为:

基于接口的动态代理(jdk自带)

基于子类的动态代理(第三方)

二、静态代理

所谓“静态 ”也就是在程序运行前就已经存在代理类的字节码文件,代理类和被代理对象的关系在运行前就确定了。

1.定义接口

interface ISinger{public void sing();
}

2.定义被代理类

public class SingerImp implements Isinger{@Overridepublic void sing(){Systm.out.println("===莫等闲===");}
}

3.定义代理类

public class SingerProxy implements Isinger{Isinger realsinger;public SingerProxy(Isinger realsinger) {this.realsinger = realsinger;}@Overridepublic void sing(){Systm.out.println("大家好");realsinger.sing();Systm.out.println("谢谢");}
}

4.定义客户端,查看执行结果

public class Test {public static void main(String[] args) {//1.创建被代理对象Isinger realsinger = new SingerImp();//2.创建代理Isinger proxysinger = new SingerProxy(realsinger);proxysinger.sing();}
}

输出结果:

大家好

莫等闲

谢谢

从上面的代码可以看出,静态代理存在被代理类和代理类之间耦合度过高。

三、动态代理

“动态”代理的源码是在程序运行期间由 JVM 根据反射等机制动态的生成,所以在运行前并不存在代理类的字节码文件。

1.使用JDk

1.1 定义接口

interface ISinger{public void sing();
}

1.2 定义被代理类

public class ZhaoYiTing implements ISinger{@Overridepublic void sing() {System.out.println("===易燃易爆炸===");}
}

1.3 定义客户端,查看执行结果

public class test01 {public static void main(String[] args) {//1.创建被代理对象ISinger zhaoYiTing = new ZhaoYiTing();//2.创建代理对象ISinger jinjiren = (ISinger)Proxy.newProxyInstance(zhaoYiTing.getClass().getClassLoader(), zhaoYiTing.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//功能增强System.out.println("===自我介绍===");Object obj = method.invoke(zhaoYiTing, args);return obj;}});jinjiren.sing();}
}

输出结果:

===自我介绍===

===易燃易爆炸===

2.使用第三方(CGLIB)

2.1 定义接口

interface ISinger{public void sing();
}

2.2 定义被代理类

public class ZhaoYiTing implements ISinger{@Overridepublic void sing() {System.out.println("莫等闲");}
}

2.3 定义客户端,查看执行结果

public class test {public static void main(String[] args) {ISing imp = new tenggeerImp();ISing jin = (ISing)Enhancer.create(imp.getClass(), imp.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object o, Method method, Object[] objects) throws Throwable {Object obj = method.invoke(imp, objects);return obj;}});jin.sing();}
}

输出结果:

莫等闲


http://www.ppmy.cn/devtools/95976.html

相关文章

<数据集>街头摊贩识别数据集<目标检测>

数据集格式:VOCYOLO格式 图片数量:966张 标注数量(xml文件个数):966 标注数量(txt文件个数):966 标注类别数:1 标注类别名称:[street-vendor] 序号类别名称图片数框数1street-vendor9662016 使用标注…

每日一问:TCP与UDP的深入探讨

每日一问:TCP与UDP的深入探讨 在网络通信中,TCP(传输控制协议)和UDP(用户数据报协议)是最常用的传输层协议。本文将详细探讨这两者的基本概念、功能差异及其在实际应用中的使用场景。通过实例和代码演示&am…

centos7卸载docker报错No Packages marked for removal

执行: yum -y remove docker* 报错: No Packages marked for removal 执行: yum list installed | grep docker yum remove -y docker-ce.x86_64 docker-ce-cli.x86_64 containerd.io.x86_64

铁电存储器(FM24W256)I2C读写驱动(1):FM24W256简介

0 参考资料 FM24W256(Cypress公司生产)数据手册 1 FM24W256铁电存储器简介 铁电存储器(FRAM)相比带电可擦可编程只读存储器(EEPROM)最突出的两个优势就是 拥有几乎无限的读写次数和写入不需要等待&#xf…

SpinalHDL之常见错误

本文作为SpinalHDL学习笔记第四十八篇,介绍 在使用 SpinalHDL 时可能出现的错误。 目录: 1.“main”线程中异常 java.lang.NullPointerException 2.层次违例 (Hierarchy violation) 1.“main”线程中异常 java.lang.NullPointerException 控制台输出&…

DataX导入或导出hive数据

DataX读取Hive数据的话,其本身只提供了hdfsreader,因为hive一来不是个数据库,它只是hdfs数据的结构化管理工具,所以你可以直接用hdfsreader,只能列名的方式抽hive数据,一般用到的抽取场景如下几类。 第一种…

Springboot项目中使用druid实现多数据源和动态数据源,因数据库不可用导致的项目挂起的处理方案

Springboot项目中使用druid因数据库不可用导致的项目挂起的处理方案 在Spring Boot项目中使用Druid实现多数据源和动态数据源管理是一个常见的场景。通过合理的配置和错误处理机制,您可以有效地管理数据源,避免因数据库不可用而导致整个项目挂起。 1.…

推出 SAM 2:适用于视频和图像的下一代 Meta Segment Anything 模型

继图像元分割模型(SAM) 取得成功之后,我们发布了SAM 2,这是一个用于在图像和视频中实时提示对象分割的统一模型,可实现最先进的性能。 为了秉承我们的开放科学方针,我们通过宽松的 Apache 2.0 许可证共享代码和模型权重。 我们还…