代理模式的理解

文章目录

  • 前言
  • 一、代理模式的定义和优、缺点
    • 定义
    • 优点
    • 缺点
  • 二、代码演示案例
    • 1.静态代理
    • 2.JDK动态代理
    • 3.CGLIB动态代理
  • 总结


前言

代理模式常见的使用场景包括:

需要对对象的访问进行控制或限制的情况。
需要在访问对象时执行额外的操作,例如记录日志、收集统计信息等。。

一、代理模式的定义和优、缺点

定义

代理模式的定义可以概括为:为一个对象提供一个代理对象,以控制对该对象的访问。

优点

1. 访问控制: 代理模式可以在客户端和原始对象之间添加一层间接层,从而实现对原始对象的访问控制。这使得代理对象可以限制客户端对原始对象的直接访问,从而保护原始对象的安全性。

2. 增强原始对象功能: 代理模式允许在访问原始对象时执行额外的操作,例如记录日志、验证用户权限、实现懒加载、缓存结果等。这些额外的功能可以在代理对象中实现,而不需要修改原始对象的代码,从而使得原始对象的功能得到增强。

3. 远程访问: 通过远程代理,客户端可以像调用本地对象一样调用远程对象,而不需要了解网络通信的细节。这使得在分布式系统中使用远程对象变得更加简单和透明。

4. 性能优化: 代理模式可以通过实现缓存代理或虚拟代理来优化系统的性能。例如,缓存代理可以缓存频繁访问的操作结果,从而减少重复计算,提高系统的响应速度。

缺点

1.复杂性增加: 引入代理对象会增加系统的复杂性,因为需要额外的类和接口来实现代理功能。这可能会增加代码量和维护成本。

2.性能损耗: 在某些情况下,代理模式可能会引入额外的性能损耗,特别是在远程代理或虚拟代理的情况下,由于需要进行网络通信或延迟加载,可能会导致一定的性能损耗。

3.可能引入单点故障: 在使用远程代理时,代理对象可能会成为系统的单点故障。如果代理对象出现故障或不可用,可能会导致客户端无法访问远程对象。

4.过多的代理类: 如果系统中存在大量的代理类,可能会导致类的数量过多,增加系统的复杂性和管理成本。

二、代码演示案例

1.静态代理

需要为每一个代理类都手动编写一个对应的代理类。代码如下(示例):

// 接口
interface Subject {void request();
}// 真实主题类
class RealSubject implements Subject {public void request() {System.out.println("RealSubject: Handling request.");}
}// 代理类
class ProxySubject implements Subject {private RealSubject realSubject;public ProxySubject(RealSubject realSubject) {this.realSubject = realSubject;}public void request() {System.out.println("ProxySubject: Logging before request.");realSubject.request();System.out.println("ProxySubject: Logging after request.");}
}// 测试类
public class Main {public static void main(String[] args) {RealSubject realSubject = new RealSubject();ProxySubject proxySubject = new ProxySubject(realSubject);proxySubject.request();}
}

2.JDK动态代理

在动态代理中,要求目标类必须实现接口,然后通过 Proxy 类和 InvocationHandler 接口动态生成代理对象。代码如下(示例):

import java.lang.reflect.*;// 接口
interface Subject {void request();
}// 真实主题类
class RealSubject implements Subject {public void request() {System.out.println("RealSubject: Handling request.");}
}// 动态代理处理器类
class DynamicProxyHandler implements InvocationHandler {private Object target;public DynamicProxyHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("DynamicProxy: Logging before request.");Object result = method.invoke(target, args);System.out.println("DynamicProxy: Logging after request.");return result;}
}// 测试类
public class Main {public static void main(String[] args) {RealSubject realSubject = new RealSubject();InvocationHandler handler = new DynamicProxyHandler(realSubject);Subject proxySubject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),handler);proxySubject.request();}
}

3.CGLIB动态代理

CGLIB通过继承目标类来生成代理类的,因此无法代理目标类中的final方法和私有方法。代码如下(示例):

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;// 需要代理的目标类
class TargetClass {public void doSomething() {System.out.println("TargetClass: Doing something...");}
}// 自定义方法拦截器
class CustomMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before invoking method: " + method.getName());Object result = proxy.invokeSuper(obj, args); // 调用目标方法System.out.println("After invoking method: " + method.getName());return result;}
}public class Main {public static void main(String[] args) {// 创建 Enhancer 对象,用于动态创建目标类的子类Enhancer enhancer = new Enhancer();// 设置目标类的父类enhancer.setSuperclass(TargetClass.class);// 设置方法拦截器enhancer.setCallback(new CustomMethodInterceptor());// 创建代理对象TargetClass proxy = (TargetClass) enhancer.create();// 调用代理对象的方法proxy.doSomething();}
}

总结

每种代理方式都有自己的适用场景和局限性。静态代理适用于简单场景下的代理,但不够灵活;JDK动态代理适用于需要在运行时动态生成代理对象,并且目标类实现了接口的情况;而CGLIB动态代理则适用于对未实现接口的类进行代理。选择合适的代理方式需要根据具体的需求和场景来决定。

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

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

相关文章

内啡肽的产生

内啡肽的产生 短视频、直播和游戏等娱乐活动可以刺激多巴胺分泌,让人感到兴奋和愉悦。这些短暂的快乐却会让我们逐渐上瘾,难以自拔。不知不觉中,我们忽略了时间的流逝,满足于现状,失去了追求更高目标的动力。 越是富…

跨ROS系统通信:使用TCP实现节点间的直连

当涉及到在机器人操作系统(ROS)环境中的通信时,标准做法通常是在同一个ROS网络内通过话题和服务进行。但在某些特定情况下,比如当你有两个分布在不同网络中的ROS系统时,标准的通信方法可能不太适用。此时,一…

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第21课-购买烟花插件

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第21课-购买烟花插件 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎…

OpenAI 5月13日推出的ChatGPT4o模型带来了什么新东西及我们需要注意什么

前言 OpenAI再次发布了新一代模型,可惜不是GPT5,发布会很长,所以我尝试看了一些自媒体对发布会做的总结视频,但是我发现这些自媒体制作的视频普遍很“营销号”味且总结的不全面,所以我看了发布会并尝试做了总结。 正…

OmniDrive:具有 3D 感知推理和规划功能的自动驾驶整体 LLM-智体框架

24年5月北理工、Nvidia和华中科大的论文“OmniDrive:A Holistic LLM-Agent Framework for Autonomous Driving with 3D Perception Reasoning and Planning”。 多模态大语言模型(MLLMs)的进展导致了对基于LLM的自动驾驶的兴趣不断增长&…

软件各阶段资料(需求设计,系统架构,开发文档,测试文档,运维阶段的部署维护文档,概要设计,详细设计)

一、 引言 (一) 编写目的 (二) 范围 (三) 文档约定 (四) 术语 二、 项目概要 (一) 建设背景 (二) 建设目标 (三&#xff0…

解决Jmeter报错 :Error generating the report: java.lang.NullPointerException

当我们在使用命令行的方式来执行jmeter 脚本的时候,例如 ./jmeter -n -t /opt/jmeter/script/test.jmx -Juser50 -Jtime100 -l /opt/jmeter/script/restult2.jtl 上面脚本的含义解释如下: -n -t 通过命令行的方式执行脚本test.jmx -Juser50 并发用户…

【贪心的商人】-华为OD

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、java代码五、测试用例 前言 本人最近再练习算法,所以会发布自己的解题思路,希望大家多指教 一、题目描述 商人经营一家店铺,有number种商品,由…

一次完整的GC流程

Java堆中内存区分 Java的堆由新生代(Young Generation)和老年代(Old Generation)组成。新生代存放新分配的对象,老年代存放长期存在的对象。 新生代(Young)由年轻区(Eden&a…

亚马逊卖家,如何打造爆款,如何提高产品权重、曝光、流量?

新老卖家们要知道,亚马逊A9算法影响产品排名的关键因素:产品相关性、销售排名、产品价格、点击率、转化率、产品图片、买家评论、买家满意度、QA的答复情况、搜索结果页详细信息级别。亚马逊A9算法,是根据卖家提供的listing文案信息进行收录、…

NIUKE SQL:大厂面试真题(四) 【某滴打车】

SQL174 2021年国庆在北京接单3次及以上的司机统计信息 问题:请统计2021年国庆7天期间在北京市接单至少3次的司机的平均接单数和平均兼职收入(暂不考虑平台佣金,直接计算完成的订单费用总额),结果保留3位小数 SELECTc…

新一代GPT!GPT-4O:更快、更懂人类情感的人工智能新纪元

今天凌晨(5.14凌晨),OpenAI 的 GPT-4O 版本在自然语言处理领域带来了革命性的改变。不仅在处理速度上获得了显著提升,GPT-4O 还增加了对人类情感的理解能力,这使得它在与人类的交互中更加自然和富有同理心。本文将深入…

嵌入式学习<2>:EXTI、ADC、NVIC和AFIO

嵌入式学习_part2 本部分笔记用于学习记录,笔记源头 >>b站江科大_STM32入门教程_EXTI EXTI、ADC、NVIC和AFIO 开发环境:keil MDK、STM32F103C8T6 1 )EXTI STM32F10xxx参考手册(中文)-> 中断与事件 ->…

[OpenGL] PCF 柔和阴影

目录 一 为什么要使用PCF技术? 二 算法 三 效果 本章节源码点击此处 一 为什么要使用PCF技术? 在阴影改善这篇文章最后我们发现阴影的边缘锯齿化很严重,对于这种问题主要是因为采样精度的问题对于不同片段有可能从深度纹理中采样到了同一个纹理像素,这就导致形成了明显的…

python 批量webp格式转换成jpg

首先,你需要安装Pillow库。如果还未安装,可以通过pip安装: pip install Pillow 创建一个Python脚本来读取webp文件,并将其转换为jpg格式。 只需修改source_folder和dest_folder变量为你的实际文件夹路径即可使用这个脚本。 fro…

InstantStyle —— 文本到图像生成中的风格保持新突破

在人工智能领域,文本到图像生成(Text-to-Image Generation)技术正迅速发展,其应用范围从娱乐到专业设计不断扩展。然而,风格一致性生成一直是该领域的一个技术难题。最近,InstantX团队提出了一种名为Instan…

MathType7.4破解版补丁包下载安装无需激活秘钥许可证

MathType是一个强大的数学公式编辑器,它为教育工作者、学生和科研人员提供了一种高效、便捷的数学公式编辑方法。无论是在撰写学术论文、制作教学课件还是进行科研报告,MathType都能满足您的需求。 MathType具有丰富的符号库和模板。它包含了几乎所有常用…

传统企业的IT如何发展

数字化时代,数字化/数字化转型是被广泛传播而又内涵不确定的概念,大家都在讨论,但每个人理解的似乎又都不一致。如果大家对数字化定义没有达成共识,那就无法明确数字化转型的成功标准是什么,方向是什么,实施…

嵌入式学习第三十五天!(算法)

算法:解决特定问题求解步骤 1. 算法的设计: 1. 正确性:语法正确;合法的输入能得到合理的结果;对非法的输入,给出满足要求的规格说明;对精心选择,甚至刁难的测试都能正常运行&#x…

Docker安装、使用及常用命令

一、Docker是什么? Docker是一种开源的容器化技术,允许开发者将应用及其运行环境打包在一个轻量级、可移植的容器中。这样,不论在开发、测试还是生产环境中,应用都能在任何Docker支持的平台上无缝运行。Docker使用Dockerfile来自…