动态代理详解

article/2025/10/31 23:00:21

想要更加透彻的理解动态代理,首先要熟悉下静态代理

一、静态代理

总结来说:目标类和代理类实现了相同的接口在代理类中依赖了目标类,代理类的方法中调用了目标类的方法,并做了一些增强性的工作。

1、实现静态代理(demo)

要求,在某个类执行类中的方法时,上下文添加一些日志记录

1)定义接口

public interface Calculate {int add(int num1,int num2);
}

2)定义委托类

public class Calculator implements Calculate {@Overridepublic int add(int num1, int num2) {System.out.println(num1 + "+" + num2 + "=" + num1 + num2);return num1 + num2;}
}

3)定义代理类

public class CalculatorWithLog implements Calculate {private Calculator calculator;public CalculatorWithLog(Calculator calculator) {this.calculator = calculator;}@Overridepublic int add(int num1, int num2) {System.out.println("add前添加一点日志");int sum = calculator.add(num1, num2);System.out.println("add后添加一点日志");return sum;}
}

4)测试

 public static void main(String[] args) {Calculator calculator = new Calculator();CalculatorWithLog calculatorWithLog = new CalculatorWithLog(calculator);calculatorWithLog.add(1, 2);}

在这里插入图片描述

2、静态代理的缺陷

  • 程序员要手动为每一个目标类编写对应的代理类。如果当前系统已经有成百上千个类,工作量太大了
  • 当接口改变时,所有的代理类都需要进行相应的变化,太过于耦合
    所以,现在我们的努力方向是:如何少写或者不写代理类,却能完成代理功能?

二、动态代理

参考B站视频:https://www.bilibili.com/video/BV1HZ4y1p7F1?p=7&vd_source=7f24cfc4e2c729f062d4a78d958bfcdf

动态代理指的是:在程序的执行过程中,使用jdk的反射机制,创建代理对象,并动态的指定代理的目标类

动态代理的实现方式常用有两种:
- 使用JDK代理
- 通过CDLIB代理

1、jdk动态代理

jdk动态代理是基于Java的反射机制实现的,使用jdk反射包下的Proxy和InvocationHandler实现代理对象的动态创建
jdk动态代理要求目标对象必须实现接口

1)InvocationHandler接口

接口中就一个方法 :invoke()
你的代理类要完成的功能就写在invoke()中

代理类需要完成的功能:

  • 调用目标类的方法
  • 功能增强,在目标方法调用时,增加功能

方法原型:
Object proxy:jdk创建的代理对象,无需赋值
Method method:目标类中的方法
Object[] args:目标类中方法的参数
public Object invoke(Object proxy, Method method, Object[] args)

2)Method类

通过Method可以执行某个目标类的方法

3)proxy类

是最核心的一个类,使用静态方法 newProxyInstance() ,创建代理对象
方法原型:
ClassLoader loader:类加载器,负责向内存中加载对象(需要使用目标对象的类加载器)
Class<?>[] interfaces:目标对象实现的接口 InvocationHandler h:我们自己写的代理类需要实现的功能 返回值就是代理对象 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h)

4)动态代理的实现步骤

  • 创建接口,定义目标类要完成的功能
public interface Calculate {int add(int num1,int num2);
}
  • 创建目标类,实现该接口
public class Calculator implements Calculate {@Overridepublic int add(int num1, int num2) {System.out.println(num1 + "+" + num2 + "=" + (num1 + num2));return num1 + num2;}
}
  • 创建 InvocationHandler 接口的实现类,在invoke()方法中完成代理类的功能
public class MyInvocationHandler implements InvocationHandler {private Object target = null;//动态代理,目标对象是活动的,不是固定的,需要传入进来public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object res = method.invoke(target, args);System.out.println("代理对象中进行功能增强....");return res;}
}
  • 使用proxy类的newProxyInstance()方法,创建代理对象,并把返回值转成接口类型
public class Test {public static void main(String[] args) {//1、创建目标对象Calculator calculator = new Calculator();//2、创建invocationHandler对象InvocationHandler invocationHandler = new MyInvocationHandler(calculator);Calculate proxyInstance =(Calculate) Proxy.newProxyInstance(calculator.getClass().getClassLoader(), calculator.getClass().getInterfaces(),invocationHandler);proxyInstance.add(1, 3);}
}

在这里插入图片描述

5)jdk动态代理的执行流程

断点打到InvocationHandler的invoke方法中,查看method和args参数
在这里插入图片描述
Proxy.newProxyInstance() 返回的对象,就是jdk创建的一个代理对象
在这里插入图片描述

6)动态代理能做什么?

在不改变原来目标方法功能的前提下,可以在代理中增强自己功能代码。

在程序开发中的意义:
- 你所在的项目中,有一个功能是其他人写好的,你可以使用,但是不能满足我的需求,我需要再增加点代码,这次就需要使用代理
来进行代码的增强,而不用改原来的代码

2、cglib动态代理(了解)

cglib是第三方的工具库,可以创建代理对象。cglib的原理是继承,cglib通过继承目标类,创建它的子类,在子类中重写父类中的方法,实现功能的修改
(要求目标类不能是final,且目标类的方法不能是final修饰的)
在这里插入图片描述


http://chatgpt.dhexx.cn/article/7taRSGeq.shtml

相关文章

CAD动态块制作

CAD动态块制作 拉伸动态块柜体A拉伸动态块制作第一步&#xff1a;制作柜体A第二步&#xff1a;进入块编辑器编辑第三步&#xff1a;关闭块编辑器 柜体B拉伸动态块制作第一步&#xff1a;制作柜体B第二步&#xff1a;进入块编辑器第三步&#xff1a;关闭块编辑器 可见性动态块第…

数据有效性 动态选择

EXCEL有两列数据栏&#xff0c;A列和B列&#xff0c;都是通过下来框来选择&#xff0c;要求A列选择完成后&#xff0c;B列动态调整可选择的内容。例如&#xff1a;第一例选择“AA”&#xff0c;第二列可供选择的范围是“a-d”&#xff1b;第一例选择“BB”&#xff0c;第二列可…

OTP 动态口令验证

OTP 动态口令验证。 简介 动态口令&#xff08;OTP&#xff0c;One-Time Password&#xff09;又称一次性密码&#xff0c;是使用密码技术实现的在客户端和服务器之间通过共享秘密的一种认证技术&#xff0c;是一种强认证技术&#xff0c;是增强目前静态口令认证的一种非常方…

loj#122.「强制在线」动态图连通性

loj#122. 「强制在线」动态图连通性 UPD:(7个月以后)这代码被叉了,我不想改了( negii真dl 然后发现这格式一更新…啊我的公式和链接怎么假掉了( csdn[] 算了不管了…反正这样子的话之后也不会用了( 题意 N 个点,M 次操作,支持加边/删边/询问两点间连通性。 强制在线。…

ORL、Yale等人脸数据库百度云链接

近段时间做人脸识别的实验&#xff0c;收集了几个人脸库&#xff0c;如图 这里放出百度云的链接&#xff0c;需要的自取 链接&#xff1a;https://pan.baidu.com/s/11_7bFdo_hhc83WQXmWtxvw 提取码&#xff1a;5ohd 强推这个文章&#xff0c;里面有16个人脸库的百度云链接 ht…

ORTP

1.为什么要使用RTP 一提到流媒体传输、一谈到什么视频监控、视频会议、语音电话&#xff08;VOIP&#xff09;&#xff0c;都离不开RTP协议的应用&#xff0c;但当大家都根据经验或者别人的应用而选择RTP协议的时候&#xff0c;你可曾想过&#xff0c;为什么我们要使用RTP来进行…

oracle中or的使用,Oracle Or

oracle函数 的 Oracle Or 在本教程中,我们来学习如何使用Oracle OR运算符来组合两个或更多的布尔表达式。 Oracle OR运算符介绍 OR运算符是一个逻辑运算符,它组合了布尔表达式,如果其中一个表达式为真(true),则返回true。 以下说明OR运算符的语法: expression_1 AND expre…

基于PCA方法的ORL人脸识别及Python代码实现

基于PCA方法的ORL人脸识别及Python代码实现 PCA算法方案设计代码实现结果分析参考文献 PCA的理论知识已经有很多博客做了清晰的解释&#xff0c;主要概括为找到投影的面使得类间误差最大&#xff0c;转化为找到构建的协方差的特征值与特征向量&#xff0c;在新的投影方向&#…

ORL Character Recgnition

文章目录 ORL Character Recgnition0 Abstract1 Introduction2 Related Work2.1 Character recognition2.2 Text detection 3 Connection Text Proposal Network3.1 Anchor3.2 Bi-Directional LSTM3.3 RPN layer3.4 Text line constructor3.5 Loss function3.6 Total system3.7…

ORL Faces Database介绍

ORL人脸数据集共包含40个不同人的400张图像&#xff0c;是在1992年4月至1994年4月期间由英国剑桥的Olivetti研究实验室创建。 此数据集下包含40个目录&#xff0c;每个目录下有10张图像&#xff0c;每个目录表示一个不同的人。所有的图像是以PGM格式存储&#xff0c;灰度图&…

基于ORL人脸数据库和PCA特征降维算法的人脸识别matlab仿真

目录 1.算法仿真效果 2.MATLAB核心程序 3.算法涉及理论知识概要 4.完整MATLAB 1.算法仿真效果 matlab2022a仿真结果如下&#xff1a; 2.MATLAB核心程序 ...................................................................... for i1:40sub_dir strcat(s, num2str(i))…

【图像处理matlab】PCA+KNN人脸识别 ORL人脸数据集

文章目录 0.写在前面1. 数据集导入与划分2. train-PCA构建脸空间2.1 原始数据导入2.2 去中心化2.3 求解协方差矩阵、特征值、特征向量2.4 特征脸选取--脸空间 3. test-物以类聚 KNN分类3.1 KNN简介3.2 KNN实现步骤3.2.1 距离度量---欧式距离、豪斯多夫距离.......3.2.2 k值选择…

Orcal 数据库

目录 一、数据库 1. 数据库概念 2. SQL 语言 3. Oracle结构 4. 表&#xff08;Table&#xff09; 5. 三范式 6. SELECT 语句 二、Orcal 基本操作 1. 查询列&#xff08;字段&#xff09; 2. 查询行&#xff08;记录&#xff09; 2.1 比较条件 2.2 且或非 2.3 null…

【人脸识别】基于PCA实现ORL人脸识别附matlab代码和报告

1 简介 人脸识别技术先进,应用广泛。借助PCA算法,利用MATLAB GUI可以简单操作,通过对待识别图像的预处理即可提高识别率。本文首先对相关概念进行了阐述,对工作原理进行了介绍,具体对基于PCA算法人脸识别的MATLAB实现进行了解析。 2 部分代码 function [neednum,average_face…

orical

truncate 和delete table 表名&#xff08;前面效率比后面高&#xff0c;而且前面执行后无法停止&#xff0c;前面会将orical查找数据时使用的节点删除&#xff0c;后面不会&#xff09; select * from 表名 会消耗大量资源不建议使用了&#xff1b; creat table 表名 as selec…

基于BP神经网络和ORL库的人脸识别matlab仿真

目录 一、理论基础 二、案例背景 1.问题描述 2.思路流程 三、部分MATLAB代码 四、仿真结论分析 五、参考文献 一、理论基础 这里&#xff0c;人脸的识别主要依据如下的流程进行&#xff1a; 具体的算法流程是这么一个过程&#xff1a; 第一&#xff1a;首先初始化一个区…

图像处理ORL--训练集及测试集建立--Matlab实现

在深度学习的研究与学习过程中&#xff0c;往往对神经网络的网络结构以及代码有比较好的理解&#xff0c;但基于matlab的数据集建立等操作经常困扰初学者。 今天带来matlab数据集建立的文件结构与代码。 文件格式 首先将图片保存在当前运行文件的文件夹中&#xff0c;将其命名…

深度学习入门_对ORL数据集进行特征提取降维后SVM分类

ORL人脸数据集共包含40个不同人的400张图像。所有图像都是以PGM格式存储的灰度图。每一个目录下的图像是在不同的时间、不同的光照、不同的面部表情条件下采集的。在该数据集中&#xff0c;每个人有10张照片。这10张照片中&#xff0c;前8张作为训练集&#xff0c;而后2张归为测…

编译原理——词法分析器实验

实验目的 掌握词法分析器的功能。掌握词法分析器的实现。 实验内容及要求 对于如下文法所定义的语言子集&#xff0c;试编写并上机调试一个词法分析程序&#xff1a; <程序>→PROGRAM <标识符>;<分程序>. <分程序>→<变量说明>BEGIN<语…

(C++)带你手肝词法分析器,容易理解,跟着思路有手就行

词法分析器 一.前言二.什么是“词法分析器”&#xff1f;三.正式设计1.设计种别码表2.设置判断为字母或数字的函数3.设置全局参数4.核心&#xff1a;scan()函数5.主函数里结合scan函数进行循环扫描6.结果截图7.需要注意&#xff08;比较难&#xff09;的地方 四.心得体会五.源代…