【设计模式】 代理模式(静态代理、动态代理{JDK动态代理、JDK动态代理与CGLIB动态代理的区别})

代理模式

代理模式是一种结构型设计模式,它提供了一种替代访问的方法,即通过代理对象来间接访问目标对象。代理模式可以在不改变原始类代码的情况下,增加额外的功能,如权限控制、日志记录等。

静态代理

静态代理是指创建的或特定工具自动生成源代码,在程序运行前代理类的.class文件就已经存在了。每个代理类只能为一个接口服务,如果需要代理多个接口,则需要编写多个代理类,这会增加维护成本。

示例:房子中介(静态代理)
// 房屋租赁服务接口
interface HouseLeaseService {void leaseHouse();
}// 真实主题类 - 房东
class Landlord implements HouseLeaseService {public void leaseHouse() {System.out.println("房东: 出租房屋.");}
}// 静态代理类 - 中介
class RealEstateAgent implements HouseLeaseService {private Landlord landlord;public RealEstateAgent(Landlord landlord) {this.landlord = landlord;}@Overridepublic void leaseHouse() {// 增加额外功能,例如广告宣传System.out.println("中介: 发布租房信息.");landlord.leaseHouse();// 增加额外功能,例如收取中介费System.out.println("中介: 收取中介费用.");}
}public class StaticProxyDemo {public static void main(String[] args) {Landlord landlord = new Landlord();HouseLeaseService agentService = new RealEstateAgent(landlord);agentService.leaseHouse();}
}

在这个例子中,RealEstateAgent作为代理类,不仅实现了HouseLeaseService接口,还包含了对Landlord对象的操作,并在调用前后添加了额外的行为。

动态代理

动态代理是在程序运行时动态生成代理类的字节码并加载到JVM中,因此不需要提前编写代理类的代码。Java提供了两种主要的动态代理方式:JDK动态代理和CGLIB。

JDK动态代理

在JDK动态代理中有两个重要的类ProxyInvocationHandler

  • Proxy
    Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
    在这里插入图片描述
    在这里插入图片描述

  • InvocationHandler
    InvocationHandler 是代理实例的调用处理程序 实现的接口。
    每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
    在这里插入图片描述

代码示例

首先,我们定义一个实现了InvocationHandler接口的处理器类ProxyInvocationHandler ,它负责封装中介的具体业务逻辑。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 房屋租赁服务接口
interface HouseLeaseService {void leaseHouse();
}// 真实主题类 - 房东
class Landlord implements HouseLeaseService {public void leaseHouse() {System.out.println("房东: 出租房屋.");}
}// 实现InvocationHandler接口的处理器类 - 中介
class ProxyInvocationHandler implements InvocationHandler {private final Object target;public ProxyInvocationHandler(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 JdkProxyDemo {public static void main(String[] args) {// 创建真实房东对象Landlord landlord = new Landlord();// 创建动态代理实例HouseLeaseService proxyInstance = (HouseLeaseService) Proxy.newProxyInstance(landlord.getClass().getClassLoader(),landlord.getClass().getInterfaces(),new ProxyInvocationHandler(landlord));// 通过代理实例调用方法proxyInstance.leaseHouse();}
}

JDK动态代理与CGLIB动态代理的区别

特性JDK 动态代理CGLIB 动态代理
实现方式只能代理实现了接口的类(基于接口)通过生成目标类的子类进行代理(基于继承)
代理类- Proxy
- Invocation Handler
- Enhancer
- Method Interceptor
核心机制使用反射调用目标方法通过ASM字节码生成目标类的子类,重写方法实现代理
性能 (jdk8)在一百万运行次数内,性能快了30%左右;到五百万运行次数后,性能快了将近一倍

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

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

相关文章

动态规划

简介 动态规划最核心两步: 状态表示:dp[i]代表什么状态转移方程:如何利用已有的dp求解dp[i] 只要这两步搞对了, 就完成了动态规划的%95 剩下的就是细节问题: dp初始化顺序(有时是倒序)处理边…

【论文笔记】On Generative Agents in Recommendation

论文信息 标题: On Generative Agents in Recommendation 会议: SIGIR 24 —— CCF-A 作者: An Zhang, Yuxin Chen, Leheng Sheng 文章链接: On Generative Agents in Recommendation 代码链接: On Generative Agents…

【动态路由】系统Web URL资源整合系列(后端技术实现)【nodejs实现】

需求说明 软件功能需求:反向代理功能(描述:apollo、eureka控、apisix、sentinel、普米、kibana、timetask、grafana、hbase、skywalking-ui、pinpoint、cmak界面、kafka-map、nacos、gateway、elasticsearch、 oa-portal 业务应用等多个web资…

【深度学习】如何一步步实现SGD随机梯度下降算法

如何一步步实现SGD随机梯度下降算法 文章目录 如何一步步实现SGD随机梯度下降算法SGD随机梯度下降算法的作用MNIST_SAMPLE数据集SGD算法的七大步骤Step1. 初始化模型参数Step2. 计算预测值predictionsStep3. 计算损失lossStep4. 计算梯度gradientsStep5. 更新模型参数Step6. 重…

Flutter 3.29.0 新特性 CupertinoNavigationBar 可配置bottom属性

Flutter 3.29版本优化了开发流程并提升了性能,对 Impeller、Cupertino、DevTools 等进行了更新。 CupertinoNavigationBar和CupertinoSliverNavigationBar现在接受底部小部件,通常是搜索字段或分段控件。 例如本小节内容就是放置了一个输入框&#xff…

Vue 3最新组件解析与实践指南:提升开发效率的利器

目录 引言 一、Vue 3核心组件特性解析 1. Composition API与组件逻辑复用 2. 内置组件与生命周期优化 3. 新一代UI组件库推荐 二、高级组件开发技巧 1. 插件化架构设计 2. 跨层级组件通信 三、性能优化实战 1. 惰性计算与缓存策略 2. 虚拟滚动与列表优化 3. Tree S…

数据结构----哈希表的插入与输出

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> typedef int datatype;typedef struct Node {struct Node *next;datatype data; }*Linklist;//创建节点 Linklist Create_node() {Linklist p(Linklist)malloc(sizeof(…

QT QLabel加载图片等比全屏自适应屏幕大小显示

最近在工作项目中,遇到一个需求: 1.使用QLabel显示一张图片; 2.当点击这个QLabel时,需要全屏显示;但不能改变原来的尺寸; 3.当点击放大后的QLabel时,恢复原有大小. 于是乎,就有了本篇博客,介绍如何实现这样的功能. 一、演示效果 在一个水平布局中&#xff0c;添加两个Lable用…

eNSP防火墙综合实验

一、实验拓扑 二、ip和安全区域配置 1、防火墙ip和安全区域配置 新建两个安全区域 ip配置 Client1 Client2 电信DNS 百度web-1 联通DNS 百度web-2 R2 R1 三、DNS透明代理相关配置 1、导入运营商地址库 2、新建链路接口 3、配置真实DNS服务器 4、创建虚拟DNS服务器 5、配置D…

ios苹果手机使用AScript应用程序实现UI自动化操作,非常简单的一种方式

现在要想实现ios的ui自动化还是非常简单的&#xff0c;只需要安装AScript这个自动化工具就可以了&#xff0c;而且安卓&#xff0c;iso还有windows都支持&#xff0c;非常好用。 在ios端安装之后&#xff0c;需要使用mac电脑或者windows电脑激活一下 使用Windows电脑激活​ 激…

CommonLang3-使用介绍

摘自&#xff1a;https://www.cnblogs.com/haicheng92/p/18721636 学习要带着目的&#xff0c;参照现实问题 本次目标&#xff1a; 了解 CommonsLang3 API 文档&#xff0c;找对路后以后开发直接查询 API 文档&#xff0c;摈弃盲目的百度掌握基础的字符串、日期、数值等工具…

Qt:多元素控件

目录 多元素控件介绍 QListWidget QTableWidget QTreeWidget 多元素控件介绍 多元素控件表示这个控件中包含了很多的元素&#xff0c;元素可能指的是字符串&#xff0c;也可以指的是更加复杂的数据结构、图片等等 Qt 中提供的多元素控件有: QListWidgetQListViewQTableW…

基于YOLO11深度学习的心脏超声图像间隔壁检测分割与分析系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分割、人工智能

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

二叉树链式结构:数据结构中的灵动之舞

目录 前言 一、 前置说明 二、二叉树的遍历 2.1前序遍历 2.2中序遍历 2.3 后序遍历 2.4层序遍历 三、二叉树的遍历的应用 3.1二叉树节点个数&#xff1a; 3.2二叉树的高度 3.3 二叉树第k层的节点的个数 3.4二叉树的查找 总结 前言 在数据结构的世界里&#xff0c;二叉…

Tomcat下载,安装,配置终极版(2024)

Tomcat下载&#xff0c;安装&#xff0c;配置终极版&#xff08;2024&#xff09; 1. Tomcat下载和安装 进入Apache Tomcat官网&#xff0c;我们可以看到这样一个界面。 现在官网目前最新版是Tomcat11&#xff0c;我用的是Java17&#xff0c;在这里我们选择Tomcat10即可。Tom…

Android Studio - Android Studio 查看项目的 Android SDK 版本(4 种方式)

一、通过项目级 build.gradle 文件 1、基本介绍 在项目级 build.gradle 文件中&#xff0c;查看 compileSdk、minSdk、targetSdk 字段 或者是 compileSdkVersion、minSdkVersion、targetSdkVersion 字段 // 看到的可能是android {compileSdk 32defaultConfig {minSdk 21tar…

linux云服务器部署deepseek,并通过网页访问

参考视频&#xff1a;https://www.douyin.com/root/search/linux%E5%AE%89%E8%A3%85%20deepseek?aid3aa2527c-e4f2-4059-b724-ab81a140fa8b&modal_id7468518885570940214&typegeneral 修改ollama配置文件 vim /etc/systemd/system/ollama.service 我的电脑硬盘只有4…

【AI】mac 本地部署 Dify 实现智能体

下载 Ollama 访问 Ollama 下载页&#xff0c;下载对应系统 Ollama 客户端。或者参考文章【实战AI】macbook M1 本地ollama运行deepseek_m1 max可以跑deepseek吗-CSDN博客 dify 开源的 LLM 应用开发平台。提供从 Agent 构建到 AI workflow 编排、RAG 检索、模型管理等能力&am…

Jenkins介绍

什么是Jenkins Jenkins 是一个开源的自动化服务器&#xff0c;主要用于持续集成和持续交付&#xff08;CI/CD&#xff09;。它帮助开发团队自动化构建、测试和部署软件&#xff0c;从而提高开发效率和软件质量。 如果一个系统是前后端分离的开发模式&#xff0c;在集成阶段会需…

如何使用 vxe-table grid 全配置式给单元格字段格式化内容,格式化下拉选项内容

如何使用 vxe-table grid 全配置式给单元格字段格式化内容&#xff0c;格式化下拉选项内容 公司的业务需求是自定义配置好的数据源&#xff0c;通过在列中配置好数据&#xff0c;全 json 方式直接返回给前端渲染&#xff0c;不需要写任何格式化方法。 官网&#xff1a;https:/…