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

代理模式学习

代理模式

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。

代理模式的目的

1.功能增强:通过代理业务对原有业务进行增强

2.控制访问:通过代理对象的方式间接的访问目标对象,防止直接访问目标对象给系统带来不必要的复杂性

静态代理

简单来说代理模式就是将被代理类包装起来然后重新实现相同的方法,并且调用原来方法的同时可以在方法前后添加一个新的处理。而这种包装可以使用继承或者组合来使用。当我们调用的时候需要使用的是代理类的对象来调用而不是原来的被代理对象。

静态代理的特点

        1.代理类是手动实现的,需要自己去创建一个类
        2.代理类所代理的目标类是固定的
静态代理可以通过继承或实现代理类的接口来实现

通过继承实现静态代理

通过继承被代理对象,重写被代理方法,可以对其进行代理。
优点:被代理类无需实现接口
缺点:只能代理这个类,要想代理其他类,要想代理其他类需要写新的代理方法。
cglib动态代理就是采用这种方式对类进行代理。不过类是由cglib帮我们在内存中动态生成的。

public class Tank{public void move() {System.out.println("Tank moving cla....");}public static void main(String[] args) {new ProxyTank().move();}
}
class ProxyTank extends Tank{@Overridepublic void move() {System.out.println("方法执行前...");super.move();System.out.println("方法执行后...");}
}

通过组合实现静态代理

定义一个被代理类需要和代理类都需要实现的接口。(接口在这里的目的就是起一个规范作用保证被代理类和代理类都实现了接口中的方法)。代理类需要将该接口作为属性,实例化时需要传入该接口的对象,这样该代理类就可以实现代理所有实现这个接口的类了。
优点:可以代理所有实现接口的类。
缺点:被代理的类必须实现接口。
JDK动态代理就是采用的这种方式实现的。同样的代理类是由JDK自动帮我们在内存生成的。

静态代理存在的问题

1.当目标类增多时,代理类也需要增多,导致代理类的关系不便

2.当接口当中的功能增多或者修改,都会影响实体类,违反开闭原则(程序对访问开放,对修改关闭)

动态代理

动态代理其实本质还是 将被代理类包装一层,生成一个具有新的相同功能的代理类。
但是与静态代理不同的是,这个代理类我们自己定义的。而动态代理这个代理类是根据我们的提示动态生成的。

相比于静态代理,动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法。

实现动态代理的方式:

1.JDK动态代理

2.CGLIB动态代理

JDK动态代理

通过java提供的Proxy类帮我们创建代理对象。
优点:可以生成所有实现接口的代理对象
缺点:JDK反射生成代理必须面向接口, 这是由Proxy的内部实现决定的。生成代理的方法中你必须指定实现类的接口,它根据这个接口来实现代理类生成的所实现的接口。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*** 使用jdk的动态代理*/
public class Tank implements Movable{@Overridepublic void move() {System.out.println("Tank moving cla....");}public static void main(String[] args) {Tank tank = new Tank();// reflection 反射 通过二进制字节码分析类的属性和方法//newProxyInstance: 创建代理对象// 参数一: 被代理类对象// 参数二:接口类对象  被代理对象所实现的接口// 参数三:调用处理器。 被调用对象的那个方法被调用后该如何处理Movable o = (Movable)Proxy.newProxyInstance(Tank.class.getClassLoader(),new Class[]{Movable.class},new LogProxy(tank));o.move();}
}class LogProxy implements InvocationHandler {private Movable movable;public LogProxy(Movable movable) {this.movable = movable;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法:"+method.getName()+"()执行前");Object invoke = method.invoke(movable, args);  // 此处相当于 movable.move()System.out.println("方法:"+method.getName()+"()执行后");return invoke;}
}interface Movable {void move();
}

CGLIB动态代理

CGLib(Code Generate Library) 与JDK动态代理不同的是,cglib生成代理是被代理对象的子类。因此它拥有继承方法实现静态代理的优点:不需要被代理对象实现某个接口。
缺点:不能给final类生成代理,因为final类无法拥有子类。

使用cglib生成代理类也很简单,只要指定父类和回调方法即可
首先需要引入依赖

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.2.12</version></dependency>
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 Main {public static void main(String[] args) {Enhancer enhancer = new Enhancer(); // 增强者enhancer.setSuperclass(Tank.class); // 指定父类enhancer.setCallback(new TimeMethodInterceptor()); // 当被代理对象的方法调用的时候会调用 该对象的interceptTank tank = (Tank)enhancer.create();  // 动态代理的生成tank.move();  // 生成之后会调用}
}class TimeMethodInterceptor implements MethodInterceptor{@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("生成的类名"+o.getClass().getName());System.out.println("生成的类的父类"+o.getClass().getSuperclass().getName());System.out.println("方法执行前,被代理的方法"+method.getName());Object result = null;result = methodProxy.invokeSuper(o, objects);System.out.println("方法执行后,被代理的方法"+method.getName());return result;}
}
class Tank{public void move(){System.out.println("Tank moving clacla....");}
}

相关文章:

代理模式学习

代理模式 代理模式是常用的java设计模式&#xff0c;他的特征是代理类与委托类有同样的接口&#xff0c;代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类&#xff0c;以及事后处理消息等。代理类与委托类之间通常会存在关联关系&#xff0c;一个代理类的对象…...

深入理解Go 语言信号量 Semaphore

1. 什么是信号量 信号量的概念是荷兰计算机科学家 1.1 P/V 操作 Dijkstra 在他的论文中为信号量定义了两个操作 : P 和 V 。 1.2 信号量和互斥锁的区别与联系 信号量有两种类型&#xff1a;二元信号量和计数信号量。 2. 信号量的 channel 实现 程序在运行时&#xff0c;…...

VisualStudio2019下载与安装

1.下载 通过百度网盘分享的文件&#xff1a;VisualStudio2019 链接&#xff1a;https://pan.baidu.com/s/16tqm0ZsOkmXTfGmi4LnGbA 提取码&#xff1a;wx60 --来自百度网盘超级会员V3的分享 2.安装...

李宏毅老师机器学习常见英语词汇

目录 1.Regression &#xff1a;回归2.Classification&#xff1a;分类3.local minima:局部最小值4.saddle point:鞍点5.ground truth:它是机器学习算法的参考标准&#xff0c;用于衡量模型的性的和判断模型的准确性6.optimization:优化 1.Regression &#xff1a;回归 2.Clas…...

人工智能时代,程序员如何保持核心竞争力?

人工智能时代&#xff0c;程序员如何保持核心竞争力&#xff1f; 随着AIGC&#xff08;如chatgpt、midjourney、claude等&#xff09;大语言模型接二连三的涌现&#xff0c;AI辅助编程工具日益普及&#xff0c;程序员的工作方式正在发生深刻变革。有人担心AI可能取代部分编程工…...

WiFi to Ethernet: 树莓派共享无线连接至有线网口,自动通过Captive Poartal网页登录认证

物联网开发系列&#xff1a;物联网开发之旅① WiFi to Ethernet: 树莓派共享无线连接至有线网口&#xff0c;自动通过Captive Poartal验证物联网开发番外篇之 Captive Portal验证原理 文章目录 背景实现工具实现细节一、将无线连接共享到以太网1. 配置静态IP地址2. 启用IP转发3…...

【神软大数据治理平台-高级动态SQL(接口开发)】

1、背景 业务部门需大数据平台按照所提需求提供企业数据接口&#xff0c;基于神软大数据治理平台-高级动态SQL功能&#xff0c;满足业务需求&#xff0c;如下&#xff1a; &#xff08;1&#xff09;业务系统需求&#xff1a; 输入&#xff1a; enterpriseName&#xff1a;…...

【Java数据结构】Map和Set超详细两万字讲解(内含搜索树+哈希表)

&#x1f512;文章目录&#xff1a; 1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; 2. Map和Set的基础概念 3.Map的基础使用 4.Set的基础使用 5. TreeMap的本质——红黑树 5.1二叉搜索树的概念 5.2二叉搜索树的模拟实现 二叉搜索树——查找 二…...

中国制造2025,会抛弃精益生产吗?

时至今日&#xff0c;“精益生产”模式依旧大行其道&#xff0c;它始终支持着中国制造业以最低的成本做出优质产品。我们认为&#xff0c;纵然是中国制造2025成为现实&#xff0c;精益生产模式也仍然是整个制造业的精髓之一。 首先&#xff0c;精益生产模式最重要的一根脊梁就是…...

Rust 循环

Rust 循环 在编程语言中&#xff0c;循环是一种重要的控制结构&#xff0c;它允许我们重复执行一段代码直到满足特定的条件。Rust 语言提供了多种循环方式&#xff0c;每种方式都有其特定的用途和语法。本文将详细介绍 Rust 中的循环&#xff0c;包括 loop、while、while let、…...

数据结构(其四)--特殊矩阵的存储

目录 11.特殊矩阵的压缩存储 &#xff08;1&#xff09;.一维数组的储存结构 &#xff08;2&#xff09;.二维数组的存储结构 &#xff08;3&#xff09;.普通矩阵的存储 &#xff08;4&#xff09;.特殊矩阵的压缩存储 i.对称矩阵 ii.三角矩阵 iii.三对角矩阵 iiii.稀疏矩…...

系统化学习 H264视频编码(06)哥伦布编码

说明&#xff1a;我们参考黄金圈学习法&#xff08;什么是黄金圈法则?->模型 黄金圈法则&#xff0c;本文使用&#xff1a;why-what&#xff09;来学习音H264视频编码。本系列文章侧重于理解视频编码的知识体系和实践方法&#xff0c;理论方面会更多地讲清楚 音视频中概念的…...

手机在网状态接口如何对接?(一)

一、什么是手机在网状态&#xff1f; 传入手机号码&#xff0c;查询该手机号的在网状态&#xff0c;返回内容有正常使用、停机、在网但不可用、不在网&#xff08;销号/未启用/异常&#xff09;、预销户等多种状态。 二、手机在网状态使用场景&#xff1f; 1.信贷审核&#…...

数据结构链表2(常考习题1)(C语言)

移除链表元素&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 解题思路&#xff1a; 情况1&#xff1a; 情…...

Rust的运行时多态

Rust的运行时多态 Rust的静态多态即编译时多态&#xff0c;通过**泛型特征约束&#xff08;Generic Type Trait Constrait&#xff09;**来实现&#xff1b; 那么动态多态&#xff08;运行时多态&#xff09;呢&#xff1f;答案是特征对象&#xff08;Trait Object&#xff…...

sqllabs通关

sqllabs5:(报错注入) ?id1 回显You are in........... ?id2-1 回显You are in........... ?id1 回显 1 LIMIT 0,1 判断是字符型&#xff0c;闭合。?id1order by 3-- //页面显示正常我们试了4行得出是报错注入 我们先爆库名 http://127.0.0.1/sqli-labs-master/L…...

RTSP系列四:RTSP Server/Client实战项目

RTSP系列&#xff1a; RTSP系列一&#xff1a;RTSP协议介绍-CSDN博客 RTSP系列二&#xff1a;RTSP协议鉴权-CSDN博客 RTSP系列三&#xff1a;RTP协议介绍-CSDN博客 RTSP系列四&#xff1a;RTSP Server/Client实战项目-CSDN博客 目录 一、RTSP Server实战项目 1、准备 2、…...

sqli-labs-php7-master第11-16关

猜注入点 先来猜数字型 单引号字符型&#xff1a; 发现注入点找到了 猜测数据库有多少个字段&#xff1a; 1’ order by 4 # 密码随便输的。 这里没有使用--注释&#xff0c;因为没作用&#xff0c;可能是过滤掉了 继续猜。刚才没猜对 1 order by 2 # 没报错&#xff0c;猜…...

c++初阶 string的底层实现

string 基础函数成员成员变量构造函数析构函数&#xff1a;拷贝构造赋值构造 遍历下标访问迭代器 增删插开辟空间push_backappendinserterase 功能函数swapfindc_strsubstrclear 其他函数比较函数流提取<<流插入>>getline 完整版 声明&#xff1a;非纯手搓&#xf…...

微信小程序实现上传照片功能

案例&#xff1a; html: <view class"zhengjianCont fontSize30" style"margin-bottom: 40rpx;"><view class"kuai"><image binderror"imageOnloadError" bind:tap"upladPhoto" data-params"business…...

SkillVLA:通过技能复用应对双-臂操纵中的组合多样性

26年3月来自新加坡国立、北京中关村学院、上海创新研究院、上海AI实验室、上海交大和复旦的论文“SkillVLA: Tackling Combinatorial Diversity in Dual-Arm Manipulation via Skill Reuse”。 视觉-语言-动作&#xff08;VLA&#xff09;模型近期取得的进展&#xff0c;已充分…...

别只拿PotPlayer看片了!挖掘它的采集录制功能,做Switch游戏存档大师

别把PotPlayer当普通播放器&#xff01;解锁它的Switch游戏录制黑科技 你是否已经厌倦了在OBS、Bandicam等专业录制软件中反复调试参数的繁琐&#xff1f;是否想过那个每天用来看视频的PotPlayer&#xff0c;其实隐藏着令人惊喜的游戏录制能力&#xff1f;今天&#xff0c;我们…...

基于声卡与电流互感器的安全交流功率测量系统设计与实践

1. 项目概述&#xff1a;用声卡安全测量交流功率我一直对各种测量技术抱有浓厚的兴趣&#xff0c;毕竟“测量即认知”这句老话在今天依然适用。对于电力消耗和产出&#xff0c;没有什么比直接测量更能说明问题了。交流功率的测量&#xff0c;核心在于同时获取电压和电流的瞬时值…...

配置OpenClaw Agent使用Taotoken作为后端模型提供商

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 配置OpenClaw Agent使用Taotoken作为后端模型提供商 基础教程类&#xff0c;指导希望使用OpenClaw等Agent工具的开发者&#xff0c…...

【紧急预警】Lindy衰减临界点已提前至第8.3个月!2024最新《营销自动化寿命健康度白皮书》限时开放前500份

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;Lindy衰减临界点的理论重构与实证突破 Lindy效应传统上描述“越老越长寿”的非线性生存规律&#xff0c;但其在现代软件系统、开源生态与协议层技术栈中的适用边界正遭遇结构性挑战。本文首次将Lindy模型从静…...

Airtest Poco实战:5分钟搞定微信小程序自动化测试环境搭建与元素抓取

Airtest Poco实战&#xff1a;5分钟搞定微信小程序自动化测试环境搭建与元素抓取微信小程序作为轻量级应用的代表&#xff0c;已经渗透到电商、社交、工具等各个领域。随着小程序功能的日益复杂&#xff0c;自动化测试成为保障产品质量的重要手段。本文将带你快速搭建微信小程序…...

如何快速掌握Avidemux:新手完整入门指南与5个核心技巧

如何快速掌握Avidemux&#xff1a;新手完整入门指南与5个核心技巧 【免费下载链接】avidemux2 Avidemux2, simple video editor 项目地址: https://gitcode.com/gh_mirrors/avi/avidemux2 Avidemux是一款功能强大且完全开源的专业视频编辑工具&#xff0c;专为快速剪辑、…...

OpenCore Legacy Patcher完整指南:如何让老旧Mac重获新生运行最新macOS

OpenCore Legacy Patcher完整指南&#xff1a;如何让老旧Mac重获新生运行最新macOS 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 想让你的老旧Mac设备重获新…...

ComfyUI-WanVideoWrapper深度解析:构建专业级AI视频生成工作流的完整方案

ComfyUI-WanVideoWrapper深度解析&#xff1a;构建专业级AI视频生成工作流的完整方案 【免费下载链接】ComfyUI-WanVideoWrapper 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-WanVideoWrapper 在AI视频生成技术快速发展的今天&#xff0c;ComfyUI-WanVi…...

BurpSuite+SqlMap深度集成:构建高可信SQL注入检测流水线

1. 这不是“点几下就出结果”的玩具&#xff0c;而是你真正能放进渗透流程里的SQL注入检测流水线很多人第一次看到“BurpSuiteSqlMap插件5分钟搞定SQL注入检测”这个标题&#xff0c;第一反应是&#xff1a;又一个标题党&#xff1f;点开全是截图堆砌、参数照抄、报错就卡住的半…...