当前位置: 首页 > news >正文

结构型模式 - 代理模式 (Proxy Pattern)

结构型模式 - 代理模式 (Proxy Pattern)

代理模式是一种结构型设计模式,它允许通过代理对象来控制对另一个对象(目标对象)的访问。代理对象充当目标对象的接口,客户端通过代理对象间接访问目标对象。


分为两大类

  • 静态代理(编译时就知道
  • 动态代理(Java程序运行时才知道

Java 静态代理

// 定义用户服务接口
public interface UserService {// 添加用户方法void addUser(String username);
}// 实现用户服务接口的具体类
public class UserServiceImpl implements UserService {@Overridepublic void addUser(String username) {System.out.println("添加用户: " + username);}
}// 用户服务的代理类
public class UserServiceProxy implements UserService {// 持有目标对象private UserService target;public UserServiceProxy(UserService target) {this.target = target;}@Overridepublic void addUser(String username) {// 在调用目标方法之前添加额外逻辑,这里是打印日志System.out.println("开始添加用户操作,记录日志...");// 调用目标对象的方法target.addUser(username);// 在调用目标方法之后添加额外逻辑,这里是打印日志System.out.println("添加用户操作完成,记录日志...");}
}// 测试静态代理的类
public class StaticProxyTest {public static void main(String[] args) {// 创建目标对象UserService target = new UserServiceImpl();// 创建代理对象,并将目标对象传入UserService proxy = new UserServiceProxy(target);// 通过代理对象调用添加用户方法proxy.addUser("张三");System.out.println();}
}

Java 动态代理又细分为两类

  • jdk 代理
  • cglib 代理
// jdk 方式import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 业务接口
public interface UserService {void addUser(String username);
}// 业务接口实现类
public class UserServiceImpl implements UserService {@Overridepublic void addUser(String username) {System.out.println("添加用户: " + username);}
}// 代理处理器
class UserServiceProxyHandler implements InvocationHandler {private final Object target;public UserServiceProxyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 在调用目标方法之前添加额外逻辑System.out.println("开始执行添加用户操作...");// 调用目标方法Object result = method.invoke(target, args);// 在调用目标方法之后添加额外逻辑System.out.println("添加用户操作执行完毕。");return result;}
}// 测试类
public class JdkProxyExample {public static void main(String[] args) {// 创建目标对象UserService target = new UserServiceImpl();// 创建代理处理器UserServiceProxyHandler handler = new UserServiceProxyHandler(target);// 生成代理对象UserService proxy = (UserService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);// 调用代理对象的方法proxy.addUser("张三");}
}
// cglib 代理import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;// 业务类
public class UserManager {public void addUser(String username) {System.out.println("添加用户: " + username);}
}// 代理拦截器
public class UserManagerInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {// 在调用目标方法之前添加额外逻辑System.out.println("开始执行添加用户操作...");// 调用目标方法Object result = proxy.invokeSuper(obj, args);// 在调用目标方法之后添加额外逻辑System.out.println("添加用户操作执行完毕。");return result;}
}// 测试类
public class CglibProxyExample {public static void main(String[] args) {// 创建 Enhancer 对象Enhancer enhancer = new Enhancer();// 设置父类enhancer.setSuperclass(UserManager.class);// 设置回调函数enhancer.setCallback(new UserManagerInterceptor());// 生成代理对象UserManager proxy = (UserManager) enhancer.create();// 调用代理对象的方法proxy.addUser("李四");}
}

对比分析

根本差异体现

代理机制

  • JDK 代理:依赖接口。在 JDK 代理示例中,UserService 是一个接口,UserServiceImpl 实现了该接口,代理对象是基于接口生成的。
  • CGLIB 代理:基于继承。在 CGLIB 代理示例中,UserManage 是一个普通类,代理对象是 UserManage 的子类。

方法调用

  • JDK 代理:在 InvocationHandler 的 invoke 方法中,使用 method.invoke(target, args) 调用目标对象的方法,这里的 target 是实际的目标对象。
  • CGLIB 代理:在 MethodInterceptor 的 intercept 方法中,使用 proxy.invokeSuper(obj, args) 调用目标类的方法,obj 是代理对象本身。

相关文章:

结构型模式 - 代理模式 (Proxy Pattern)

结构型模式 - 代理模式 (Proxy Pattern) 代理模式是一种结构型设计模式,它允许通过代理对象来控制对另一个对象(目标对象)的访问。代理对象充当目标对象的接口,客户端通过代理对象间接访问目标对象。 分为两大类 静态代理&#…...

el-select滚动获取下拉数据;el-select滚动加载

el-select下拉获取数据 1.解决问题2.封装MyScrollSelect组件3.使用MyScrollSelect组件 1.解决问题 场景:下拉数据量过大,后端提供一个分页查询接口;需要每次滚动加载下一页的下拉数据 且单选的状态,需要支持回显,通过n…...

HTTP GET 请求示例

鸿蒙操作系统(HarmonyOS)是华为公司自主研发的面向全场景的分布式操作系统,旨在为用户提供一个安全、流畅且跨设备无缝连接的体验。它支持多种终端设备,如智能手机、平板电脑、智能电视、汽车等,并实现了模块化解耦&am…...

简单理解Oracle中的latch

可以用一个小卖部抢购的例子来理解 Oracle 数据库中的 Latch: 1、 什么是 Latch? 打个比方,假设数据库的某个内存区域(比如缓存的数据块)是小卖部货架上的最后一包辣条,Latch 就像是货架前的一个狭窄通道&a…...

ubuntu新系统使用指南

1. 更新源 2. 配置rime 输入法 sudo apt install ibus-rimeibus-setup #打开配置界面添加雾凇拼音 cd ~/Documents/Tool/input_source/plumgit clone --depth 1 https://github.com/rime/plum plum #没有梯子就劝退cd plum/bash rime-install iDvel/rime-ice:others/recipe…...

sage-huga改进SITAN

Sage-Husa自适应滤波算法 Sage-Husa自适应滤波算法是一种在递推滤波过程中实时估计和修正系统噪声和观测噪声统计特性的算法,从而降低系统模型误差,提高滤波精度。该算法基于卡尔曼滤波,并通过自适应调整噪声协方差矩阵来优化滤波效果。 算法原理 Sage-Husa滤波器的核心思…...

DeepSeek开源周Day1:FlashMLA引爆AI推理性能革命!

项目地址:GitHub - deepseek-ai/FlashMLA 开源日历:2025-02-24起 每日9AM(北京时间)更新,持续五天! ​ 一、开源周震撼启幕 继上周预告后,DeepSeek于北京时间今晨9点准时开源「FlashMLA」,打响开源周五连…...

Git add --- error: Filename too long

0 Preface/Foreword 1 解决办法 git config --system core.longpaths true...

Python入门12:面向对象的三大特征与高级特性详解

面向对象编程(OOP)是Python编程中非常重要的一部分,它通过封装、继承和多态这三大特征,帮助我们更好地组织和管理代码。除此之外,Python还提供了一些其他特性,如类属性、类方法和静态方法,进一步…...

动态链接器(九):.init和.init_array

ELF文件中的.init和.init_array段是程序初始化阶段的重要组成部分,用于在main函数执行前完成必要的初始化操作。 1 .init段和.init_array 段 1.1 作用 .init段包含编译器生成的初始化代码,通常由运行时环境(如C标准库的启动例程&#xff0…...

Elasticsearch:使用经过训练的 ML 模型理解稀疏向量嵌入

作者:来自 Elastic Dai Sugimori 了解稀疏向量嵌入,理解它们的作用/含义,以及如何使用它们实现语义搜索。 Elasticsearch 提供语义搜索功能,允许用户使用自然语言进行查询并检索相关信息。为此,目标文档和查询必须首先…...

安宝特方案 | 电力行业的“智能之眼”,AR重新定义高效运维!

引言: 电力行业正经历智能化变革,安宝特AR数字化工作流以四大核心优势,为电力企业打造全场景智慧运维方案! 四大颠覆性功能,直击行业痛点 1、高度自定义作业流程 支持图文指引、语音播报、AI实时识别(如…...

【落羽的落羽 数据结构篇】树、二叉树

文章目录 一、树1. 树的概念和结构2. 树的相关术语 二、二叉树1. 概念与结构2. 满二叉树3. 完全二叉树4. 二叉树的性质5. 二叉树的存储结构 一、树 1. 树的概念和结构 之前我们学习了线性表,今天我们再来接触一种全新的数据结构——树。 树是一种非线性的数据结构…...

[回顾]从原型链视角解读Vue底层实现Vue VueCompoent VM VC关系

从原型链视角解读VueComponent与Vue关系 原型链 根据,原型链涉及三个关键属性:__proto__是所有对象的私有属性,指向原型链的第一个元素;prototype是函数的属性,实例对象不拥有它;constructor指向构造函数。提到原型链是JS中实现继承的机制,通过属性链式查找属性,直到…...

springcloud nacos 整合seata解决分布式事务

文章目录 nacos安装Mysql5.7安装及表初始化seata server安装下载并解压seata安装包在conf文件夹修改file.conf文件向本地数据库导入seata需要的表修改registry.conf文件将seata配置信息添加到nacos配置中心启动seata server springcloud整合seata测试流程正常下单流程扣减库存失…...

【算法系列】快速排序详解

文章目录 快速排序的多种实现方式1. 基本快速排序(Lomuto 分区方案)1.1 基本原理1.2 步骤1.3 Java 实现示例 2. Hoare 分区方案2.1 基本原理2.2 步骤2.3 Java 实现示例 3. 三数取中法3.1 基本原理3.2 步骤3.3 Java 实现示例 4. 尾递归优化4.1 基本原理4.…...

神经网络发展简史:从感知机到通用智能的进化之路

引言 神经网络作为人工智能的核心技术,其发展历程堪称一场人类对生物大脑的致敬与超越。本文将用"模型进化"的视角,梳理神经网络发展的五大关键阶段,结合具象化比喻和经典案例,为读者呈现一幅清晰的AI算法发展图谱。 一…...

C语言番外篇(4)--------->goto语句

在C语言中,有一个很特殊的语法,这就是goto语句。goto用于实现同一函数的跳转,goto后面会有一个标志,执行goto语句时,就会跳转到标志的位置。 一、goto语句的语法 (1)goto在前,标志…...

AI 编码 2.0 分析、思考与探索实践:从 Cursor Composer 到 AutoDev Sketch

在周末的公司【AI4SE 效能革命与实践:软件研发的未来已来】直播里,我分享了《AI编码工具 2.0 从 Cursor 到 AutoDev Composer》主题演讲,分享了 AI 编码工具 2.0 的核心、我们的思考、以及我们的 AI 编码工具 2.0 探索实践。 在这篇文章中&am…...

Linux与自动化的基础

Linux简介 Linux是一种开源的类Unix操作系统,广泛应用于服务器、桌面和嵌入式设备。常见的Linux发行版包括 Ubuntu、CentOS 和 Debian,它们各有特色,但都以稳定性和安全性著称。 与图形界面相比,Linux的**命令行界面&#xff08…...

不锈钢彩涂板哪个靠谱

最近好几个做工程的朋友跟我吐槽,说厂房屋顶的彩涂板用了不到三年就开始生锈、掉漆,维修成本比当初省的那点钱高多了。这让我想起去年帮一个化工厂选材的经历,当时对比了市面上好几家,最后才明白:选不锈钢彩涂板&#…...

基于**半导体无功老化上位机实战经验**(多站点、可配置硬件、PLC+负载监控+主板+RFID+扫码枪)

✅ 完成优化与完整架构设计 基于半导体无功老化上位机实战经验(多站点、可配置硬件、PLC负载监控主板RFID扫码枪),给出稳定、生产级、可直接落地的完整架构 核心代码。 1. 项目分层结构(严格按您要求命名) MaxWell.So…...

如何在Windows上直接安装APK文件:APK-Installer终极指南

如何在Windows上直接安装APK文件:APK-Installer终极指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否厌倦了笨重的安卓模拟器?想要在W…...

Apache日志文件也能被黑?手把手教你复现access.log文件包含漏洞(DVWA靶场实战)

Apache日志文件的安全隐患:从记录工具到攻击载体的转变 在网络安全领域,最危险的漏洞往往隐藏在最不起眼的地方。Apache服务器的access.log日志文件,这个看似无害的系统记录工具,在特定条件下可能成为攻击者入侵系统的跳板。本文将…...

从旋钮到转速:Arduino PWM 直流电机调速实战解析

1. 从零开始:PWM电机控制的核心原理 第一次接触电机控制时,我完全被PWM这个概念搞懵了。什么占空比、频率、脉宽调制,听起来就像天书。直到有天我盯着电风扇发呆,突然明白了:PWM其实就是让电机"喘口气"的技术…...

倍福NC轴编码器参数实战:从基础释义到高级配置避坑指南

1. 编码器参数基础:从零理解核心概念 第一次接触倍福NC轴编码器参数时,我盯着那一堆英文参数名和十六进制数值直发懵。后来在调试第三方驱动器的过程中踩过几次坑才明白,这些参数本质上是在建立编码器脉冲与实际物理位置之间的"翻译规则…...

从交流到直流:用一颗BL0910芯片搞定多路电能监测的硬件设计与SPI通信要点

从交流到直流:BL0910芯片在多路电能监测中的硬件设计与SPI通信实战 在能源管理系统中,精确测量交直流电能是核心需求。BL0910作为一款高度集成的计量芯片,能够同时处理多达10路的交直流混合信号,为智能电表、工业监控设备提供了高…...

AIAgent语音识别不再依赖云端?2026奇点大会宣布边缘侧实时ASR芯片流片成功(功耗<1.2W,词错率提升41.6%)

第一章:2026奇点智能技术大会:AIAgent语音识别 2026奇点智能技术大会(https://ml-summit.org) 实时流式语音识别架构演进 本届大会重点展示了新一代AIAgent语音识别引擎——SonicCore v4.2,其核心突破在于将端到端流式识别延迟压缩至平均12…...

如何快速完成Axure RP汉化:零基础用户的完整中文界面解决方案

如何快速完成Axure RP汉化:零基础用户的完整中文界面解决方案 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为…...

从产品经理视角看技术实现:拆解‘苍穹外卖’套餐管理的业务逻辑与接口设计

从产品经理视角看技术实现:拆解‘苍穹外卖’套餐管理的业务逻辑与接口设计 在数字化餐饮服务领域,套餐管理模块的设计直接影响运营效率和用户体验。作为连接商业策略与技术落地的关键环节,产品经理需要深入理解业务规则如何转化为系统约束&am…...