代理模式详细讲解

article/2025/10/2 9:23:00

文章目录

  • 一、什么是代理模式?
  • 二、 为什么使用代理模式?
  • 三、 代理模式的实现
    • 1、静态代理
      • 1.1、 创建公共的接口
      • 1.2、 创建被代理角色
      • 1.3、 创建代理角色
      • 1.4、 创建测试类
    • 2、动态代理的实现
      • 2.1、 使用 JDK 的 Proxy 类实现动态代理
        • 1、 创建业务接口
        • 2、 创建接口实现类
        • 3、 创建生成代理对象的工厂
        • 4、 创建切面对象
        • 5、 创建测试类
      • 2.2、 使用 CGLIB 实现动态代理
        • 1、添加 jar 包
        • 2、 创建业务接口
        • 3、创建接口实现类
        • 4、创建生成代理对象的工厂
        • 5、 创建切面
        • 6、 创建测试类


一、什么是代理模式?

代理模式(Proxy Pattern):代理模式是 Java 常见的设计模式之一。所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理对象,来间接的调用实际的对象。通俗的来讲代理模式就是我们生活中常见的中介。
在这里插入图片描述

二、 为什么使用代理模式?

  • 隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
  • 开闭原则:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。

代理模式的优点:
在这里插入图片描述
代理模式的缺点:
在这里插入图片描述

三、 代理模式的实现

代理模式可以分为两种:静态代理、动态代理。

1、静态代理

静态代理模式由三个部分构成:

  • 一个公共的接口
  • 一个被代理角色
  • 一个代理角色

1.1、 创建公共的接口


//公共接口
public interface Rent {void renting();
}

1.2、 创建被代理角色


//被代理对象
public class Corey implements Rent{//这是被代理对象!(房主)@Overridepublic void renting() {System.out.println("Corey有房出租");}
}

1.3、 创建代理角色

//代理对象(中介)
public class StaticProxyRent implements Rent{private Rent rent;public StaticProxyRent(Rent rent){this.rent = rent;}@Overridepublic void renting() {System.out.println("向房客出租房屋");this.rent.renting();System.out.println("完成售后服务");}
}

1.4、 创建测试类

public class StaticProxyTest {public static void main(String[] args) {Rent rent = new Corey();StaticProxyRent staticProxyRent = new StaticProxyRent(rent);staticProxyRent.renting();}
}

2、动态代理的实现

在动态代理中分为两种实现方式:

  • 使用 JDK 的 Proxy 类实现动态代理
  • 使用 CGLIB 实现动态代理

2.1、 使用 JDK 的 Proxy 类实现动态代理

1、 创建业务接口

public interface JdkProxyRent {void renting();
}

2、 创建接口实现类

public class JdkProxyCorey implements JdkProxyRent {@Overridepublic void renting() {System.out.println("Corey 有房出租!");}
}

3、 创建生成代理对象的工厂

//动态生成代理对象的工厂
public class JdkProxyFactory {//动态生成代理对象public static Object getProxyBean(Object target){Class clazz = target.getClass();MyAspect myAspect = new MyAspect();//在JDK中动态生成代理对象的方法return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {//动态生成代理对象的方法@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {myAspect.before();Object obj =  method.invoke(target,args);myAspect.after();return obj;}});}
}

4、 创建切面对象


public class MyAspect {public void before(){System.out.println("带领房客看房...签租房协议");}public void after(){System.out.println("售后服务");}
}

5、 创建测试类

public class jdkProxyTest {public static void main(String[] args) {JdkProxyRent jdkProxyRent = new JdkProxyCorey();JdkProxyRent jdkProxyRent1 =(JdkProxyRent)JdkProxyFactory.getProxyBean(jdkProxyRent);jdkProxyRent1.renting();}
}

2.2、 使用 CGLIB 实现动态代理

CGLIB(Code Generation Library)是一个高性能开源的代码生成包,它被许多框架所使用,其底层是通过使用一个小而快的字节码处理框架 ASM(Java 字节码操控框架)转换字节码并生成新的类。因此 CGLIB 要依赖于 ASM 的包。
JDK 的动态代理机制只能代理实现了接口的类,而对于没有实现接口的类就不能使用JDK 的 Proxy 类生成代理对象,cglib 是针对类来实现代理的,他的原理是对指定的目标类生成一个子类并通过回调的方式来实现增强,但因为采用的是继承,所以不能对 final 修饰的类进行代理。

1、添加 jar 包

cglib.jar
asm.jar

2、 创建业务接口

public interface CglibProxyRent {void renting();
}

3、创建接口实现类


public class CglibProxyCorey implements CglibProxyRent {@Overridepublic void renting() {System.out.println("Corey 有房出租");}
}

4、创建生成代理对象的工厂

public class CglibProxyBeanFactory {public static Object getProxyBean(CglibProxyRent rent){CglibMyAspect myAspect = new CglibMyAspect();Enhancer enhancer = new Enhancer();enhancer.setSuperclass(rent.getClass());enhancer.setCallback(new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {myAspect.before();Object obj = method.invoke(rent,objects);myAspect.after();return obj;}});return enhancer.create();}
}

5、 创建切面

public class CglibMyAspect {public void before(){System.out.println("带领客户看房,签订租房协议");}public void after(){System.out.println("售后服务");}
}

6、 创建测试类

public class Test {public static void main(String[] args) {CglibProxyRent rent = new CglibProxyCorey();CglibProxyRent rent1 = (CglibProxyRent) CglibProxyBeanFactory.getProxyBean(rent);rent1.renting();}
}


http://chatgpt.dhexx.cn/article/4djpYtFZ.shtml

相关文章

一文搞懂代理模式

代理模式 前言一、代理模式是什么?二、静态代理三、动态代理1.jdk动态代理(接口代理)2.cglib动态代理 前言 一、代理模式是什么? 代理模式是常见的设计模式之一,顾名思义,代理模式就是代理对象具备真实对象…

手机测试耳机音质的软件,耳机音质测试软件有哪些

耳机音质测试软件并不存在,因为耳机的音质对于人来说是主观的,你认为音质好的耳机,有的人却并不认为也很正常,国内外都没有恒定的耳机音质评判标准,大多数人认为音质好的耳机,那么它十有八九实际就是好的。…

软件测试的基本理论与方法

文章目录 前言软件测试基础1. 软件测试的概念2. 软件测试的目的 测试用例1. 测试用例的概念2. 测试用例的分类3. 测试用例的治理4. 测试用例的编制及使用5. 测试需求 软件生命周期1. 问题的定义及规划2. 需求分析3. 软件设计4. 程序编码5. 软件测试6. 运行维护7. 生命周期模型 …

固态硬盘测试软件有哪些,SSD测试软件有哪些?SSD测试软件盘点

在购买了固态硬盘(SSD)后,如果对商家或官方给出的诸如读写速度等关键性数据存在质疑的话,最好的解决方法莫过于通过SSD测试软件来找寻答案。那么,SSD测试软件有哪些?SSD测试软件哪个比较好用呢?针对上述问题&#xff0…

软件工程-软件测试-测试方法

软件工程-测试方法-白盒和黑盒测试 软件工程-软件测试 软件测试方法可以分为静态测试和动态测试。 静态测试 静态测试是指被测试程序不在程序上运行,而是采用人工检测和计算机辅助金泰分析的手段对程序进行检测。 静态测试方法 (1)人工检…

软件测试方法和技术有哪些?

软件测试方法和技术有哪些?包括软件测试基础、软件测试方法、软件测试流程和规范、单元测试与集成测试、系统测试、验收测试、软件本地化测试、测试自动化及其框架、白盒测试和黑盒测试等。 软件测试方法技术   软件测试方法: 一、等价类测试方法的…

软件测试方法汇总 - 从不同角度分析软件测试方法有哪些

1、从是否关心内部结构来看 (1)白盒测试:又称为结构测试或逻辑驱动测试,是一种按照程序内部逻辑结构和编码结构,设计测试数据并完成测试的一种测试方法。 (2)黑盒测试:又称为数据驱…

常见的软件测试方法有,常见的几种软件测试方法都有哪些

随着互联网的不断发展,越来越多的人也都开始学习软件测试的相关技术,而今天我们就一起来了解一下,常见的几种软件测试方法都有哪些。 1、单元测试 单元测试测试的是代码库的单元。 它们直接调用函数或单元,并确保返回正确的结果。…

Dynatrace系列之- 标记常见问题

Dynatrace系列之- 标记常见问题 在大型环境中,系统的某些方面可能会持续触发不必要的警报。这些告警可能来自非关键组件或者是非关键情况下的资源不足的问题。通常这些问题不需要人员响应。 为了减少此类警报并避免发出垃圾告警邮件,Dynatrace AI根因分…

什么是 Dynatrace 里的 Visually Complete 度量标准

Dynatrace 中的 Visually Complete 是一个度量标准,用于测量在加载过程中用户在页面上看到的内容。Visually Complete 指标是当一个用户看到页面上的所有重要元素并且它们正确地渲染时所测量的时间点。这意味着所有可见的文本、图像和视频都已加载并正确显示。该指标…

DevSecOps 团队请避免陷入这些可观测性陷阱

如果您发现难以管理跨越多个云运行不断变化的容器化工作负载的庞大基础架构,那么您并不孤单。 根据 Dynatrace 近期发布的一项研究,超过一半的组织的 DevSecOps 团队在可观测性数据方面感到痛苦。 多云和混合计算设置的兴起,使大部分组织能够…

前端性能分析工具Dyna Trace使用心得(转)

什么是dynatrace ajax “dynatrace ajax 是一个详细的底层追踪工具,它不仅可以显示所有请求和文件在网络中传输的时间,还会记录浏览器render,CPU消耗、JS解析和运行情况等详细的信息,而这些也只是dynatrace ajax的冰山一角。” 为…

使用dynatrace+showslow进行前端性能测试

原文:http://blog.csdn.net/zhangren07/article/details/6883617 1.背景 应用的性能测试与优化目前主要停留在服务器端的反馈,而对于前端性能标准的研究与测试相对比较空白,缺乏统一的标准与工具。众所周知,浏览器html组件的下载…

什么是 Dynatrace 里的 User Action

用户操作是与最终用户界面的交互,涉及对 Web 服务器的调用,这可能有多个嵌套调用。 它是由用户输入(例如页面加载、单击或触摸)触发的从一个视图到另一个视图的转换。 Web 应用的 User Action 类型: Load actionsXHR …

Ultra Fast Deep Lane Detection with HybridAnchor Driven Ordinal Classification

Abstract 我们将车道检测过程视为一个使用全局特征的锚定驱动的有序分类问题。 首先,我们在一系列混合(行和列)锚点上用稀疏坐标表示车道。在锚驱动表示的帮助下,我们将车道检测任务重新表述为一个有序分类问题,以得到…

Dynatrace系列之-排除干扰请求

排除干扰请求 Dyatrace监控了所有服务端的请求。当特定请求的性能或者失败率高的时候,Dynatrace将触发告警。然尔不是所有的高并发的请求都是重要的请求,有些慢请求也不需要告警。比如心跳请求。这些不重要的请求可能会干扰整个服务(service)的响应时间…

Web Performance工具 – Dynatrace AJAX Edition

Dynatrace AJAX Edition是我认为最为强大的Web Performance Profile工具。废话不说了,直接上图介绍其主要功能。 先用IE访问你需要profile的网站,例如google,可以点击dynatrace工具栏来启动。这时候dynatrace就开始记录这个网站触发的一切事件。 我简单测试一下,点击googl…

DynamicArray

文章目录 1 DynamicArray设计要点2 继承关系图和接口实现3 代码实现4 代码优化 1 DynamicArray设计要点 类模板 动态确定内部数组空间的大小实现函数返回数组长度构造拷贝和赋值操作 2 继承关系图和接口实现 继承关系图 接口实现 template < typename T > class D…

云途加油站 | 一文读懂 Dynatrace 与 Amazon Lambda 的“双剑合璧心法”

Amazon Lambda 正在掀起企业级云市场的一场小潮流。不少业内人士发现&#xff0c;越来越多的企业正在将 Lambda 函数加入其技术栈中。 这一潮流其实不难理解—— 一则&#xff0c;门槛低。Amazon Lambda为企业进入云计算提供了相对较低的门槛&#xff0c;无需立即全面推行转移…

Dynatrace AppMon最佳实践(一)

经常有客户问我,如何利用Dynatrace捕获必要的应用性能监控信息,从而快速诊断性能问题?所谓捕获必要的信息,即是在应用出现性能下降的时候,PurePath能够捕获导致事务响应缓慢的方法,或是导致事务失败的异常栈信息,亦或是用户请求的上下文参数。如何通过Dynatrace捕获必要…