JKD动态代理

article/2025/10/20 0:49:48

一、说明

在Java的动态代理机制中,有两个重要的类和接口,一个是InvoInvocationHandler(接口)、Proxy(类),这一个类和接口是我们动态代理所必须用到的。

在这里插入图片描述

优点:

  • 对于实现了接口的类,可以直接使用基于接口的动态代理进行代理,非常方便
  • 代理类和被代理类都必须实现同一个接口,能够实现对被代理对象的方法调用进行统一管理。
  • 性能上:在老版的jdk,jdk代理生成的类速度快,通过反射调用慢,cglib是jdk代理速度的10倍左右,jdk在版本每次升级都会有很大的性能提升,cglib停滞不前,jdk7 8的动态代理性能在1万次实验中比cglib要快20%左右
  • jdk动态代理如果目标类未实现接口则无法代理,cglib是通过继承的方式来动态代理,若目标类被final关键字修饰,则无法使用cglib做动态代理

缺点:

  • 只能代理实现了接口的类,对于没有实现接口的类无法使用此种方式进行代理。
  • jdk动态代理只提供实现接口的目标类代理,不支持没有实现接口的目标类的代理。如果目标类没有实现接口,只能用cglib代理

二、主要类方法的说明

InvocationHandler接口:

每个动态代理类都必须实现InvocationHandler接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler接口的invoke方法来进行调用。

InvocationHandler接口的invoke方法
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
proxy:  - 指代我们所代理的那个真实对象
method: - 指代的是我们所要调用真实对象的某个方法的Method对象
args:  - 指代的是调用真实对象某个方法时接受的参数**proxy存在的意义:**
1. 可以使用反射获取代理对象的信息(也就是proxy.getClass().getName())。
2. 可以将代理对象返回以进行连续调用,这就是proxy存在的目的,因为this并不是代理对象。

Proxy 类:

Proxy类的作用就是用来动态创建一个代理类对象的类,它提供了许多的方法,但是我们用的最多的就是newProxyInstance这个方法

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
loader:   一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
interfaces:  一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
h:   一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
  • 打印代理的类:
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

三、关键步骤

  1. 创建InvocationHandler实现类
public class MapperProxy<T> implements InvocationHandler {private Class<T> proxyInterface;//这里可以维护一个缓存,存这个接口的方法抽象的对象MapperProxy(Class<T> proxyInterface){this.proxyInterface = proxyInterface;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("执行前...");Constructor constructor  = proxyInterface.getConstructor();Object o =  constructor.newInstance();method.invoke(o,args);System.out.println("执行后");return null;}
}
  1. 通过 Proxy.newProxyInstance() 创建代理实例
 Fly fly = (Fly) Proxy.newProxyInstance(MyFly.class.getClassLoader(),new Class[]{Fly.class, Fly.Fly2.class},new MapperProxy<>(MyFly.class));

在这里插入图片描述

-  创建代理类-   Class<?> cl = getProxyClass0(loader, intfs);
-  获取有参构造器  Constructor<?> cons = cl.getConstructor(constructorParams);这里的参数就是InvocationHandler
-  通过构造器创建代理实例-参数就是方法的第三个参数
  1. 分析生成的代理类
    在这里插入图片描述
    在这里插入图片描述

结论:

  • 代理类会继承Proxy ,这里也就解释了为什么通过JDK生成的代理无法代理非接口实现类了
  • 代理类实现了传入的所有接口类型
  1. 调用代理类的doFly()
  • 这里会调用 super.h.invoke(this, m3, (Object[])null);
  • super.h就是我们再创建代理对象是传入的MapperProxy,所有这里会执行MapperProxy.invoke方法(在这里我们就可动态的对该执行方法进行增强)
    在这里插入图片描述

http://chatgpt.dhexx.cn/article/WmFlhTPg.shtml

相关文章

JDO

如何用JDO开发数据库应用 &#xff08;本文的版权属作者本人&#xff0c;欢迎转载&#xff0c;但必须注明出处和原作者&#xff09; 本文将介绍如何使用Sun公司的最新《Java Data Objects 》规范来进行基于数据库的简单应用程序的开发&#xff0c;从而使读者对JDO有一个直接的感…

亲测Linux服务器安装JKD操作流程

下载地址&#xff1a; 链接: https://pan.baidu.com/s/14aOlotFFQy6KQ05T1t2iyw 提取码: 67t4 青华大学&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/Adoptium/8/jdk/x64/linux/ 1.添加Linux命令&#xff08;默认没有上传命令&#xff09; yum install lrzsz 2.查看JKD是…

J D B C

文章目录 前言一、jdbc是什么&#xff1f;二、使用步骤三、sql注入三、封装四、ORM(object rational mapping)五、日期类六&#xff0c;事务七&#xff0c;三层架构八&#xff0c;连接池 前言 一、jdbc是什么&#xff1f; JDBC&#xff08;Java DataBase Connectivity,java数…

jkd环境配置

这里写目录标题 1.下载jdk2. 安装jdk3.配置环境4.验证 1.下载jdk https://www.oracle.com/java/technologies/javase-jdk16-downloads.html&#xff08;下载链接&#xff09; 2. 安装jdk 只需要自定义安装路径&#xff0c;其余不动 3.配置环境 我的电脑&#xff08;右键&a…

JKD+Tomcat+Eclipse基础配置

目录 一、JDK环境变量配置&#xff1a;java&#xff08;jdk需安装&#xff0c;根据向导安装&#xff0c;无需修改&#xff09; 二、检查是否配置成功: 三、Tomcat环境变量配置&#xff1a;java&#xff08;jdk需安装&#xff09;和Tomcat&#xff08;需解压&#xff09; 四、…

Linux之jkd、tomcat、mysql安装

目录 一、安装JDK1、将jdk解压到/opt下2、配置环境变量1&#xff09;vi /etc/profile2&#xff09;在最后面配置JDK环境变量3&#xff09;设置环境变量生效4&#xff09;检查JDK环境变量 二、安装Tomcat1.解压Tomcat2.配置环境变量1&#xff09;vi /etc/profile2&#xff09;在…

在java中jkd中文意思_Java JDK是什么意思?有什么作用?

下面我们介绍&#xff0c;Windows7 和 Windows10下载安装JDK与JDK环境配置的方法。 (1)下载JDK(获取【JDK8、11、15全系列版本】【Java高级程序员学习路线图】【0基础Java视频资料】加播妞 &#xff1a;2217622915) https://www.oracle.com/technetwork/java/javase/overview/i…

在Linux中安装JKD(详细教学)

一&#xff0c;首先在官网下载Linux版JKD 官网&#xff1a;Oracle | Cloud Applications and Cloud Platform 二&#xff0c;通过xftp上传工具将jdk上传到linux中 三&#xff0c;将JKD解压到指定文件夹 linux命令&#xff1a; tar -xvf 压缩包名称.tar.gz -C /usr/lib/jvm …

jkd的安装与配置

jkd的安装与配置 下载JDK 下载地址,点击进入: www.oracle.com/technetwork/java/javase/downloads/index.html下载JDK——进入下载主页 点击下载JDK,会出现图1-9所示的下载列表界面。首先,点击”Accept License Agreement”,然后选择对应的版本,下载即可。 下载JDK——…

Java学习第一天:jkd安装、环境变量配置和第一个程序

第一天笔记 jdk的安装 下载jdk jdk是Java开发环境。其中包括了Java编译器、Java运行工具、Java生成文档工具、Java打包工具等。Java开发环境中自带了一个Java运行环境运行工具JRE。因此&#xff0c;安装过程中不需要安装JRE了。 到Oracle官网中下载&#xff0c;甲骨文官网地址…

java getopt_sys.argv和getopt.getopt()的用法

Python中sys.argv是命令行参数从程序外部传值的的一种途径&#xff0c;它是一个列表&#xff0c;列表元素是我们想传进去的的新参数&#xff0c;所以可以用索引sys.argv[]来获得想要的值。因为一个写好的程序一般封装好了&#xff0c;直接在编辑软件里运行就行了&#xff0c;但…

命令行参数解析函数 getopt、getopt_long

getopt 函数在头文件 <unistd.h> 中&#xff0c;它可以解析我们传入的命令行参数。 可以实现类似 gcc -o 、rm -rf 等命令。 man 3 getopt 。在线版&#xff1a;http://man.he.net/?topicgetopt&section3 #include <unistd.h>int getopt(int argc, char * co…

C/C++ 命令解析:getopt 方法详解和使用示例

一、简介 getopt() 方法是用来分析命令行参数的&#xff0c;该方法由 Unix 标准库提供&#xff0c;包含在 <unistd.h> 头文件中。 二、定义 int getopt(int argc, char * const argv[], const char *optstring);extern char *optarg; extern int optind, opterr, optop…

*args和**kwargs

*args和**kwargs的区别 首先*args和**kwargs的区别主要是*和**的区别&#xff0c;与变量名args和kwargs无关&#xff0c;也可以命名成*cat和**dog&#xff1b;*args接收不带变量名的变量&#xff0c;**kwargs接收带变量名的变量。*args和**kwargs可以共同使用&#xff0c;但是顺…

python中argparse模块关于 parse_args() 函数详解(全)

目录 前言1. 函数讲解2. 基本用法3. 实战讲解 前言 原理&#xff1a;命令行解析使用argparse包作用&#xff1a;命令行传参赋值 可用在机器学习深度学习 或者 脚本运行等 了解这个函数需要了解其背后的原理以及具体参数 1. 函数讲解 在深度学习模型框架中几乎都有的模块 浓…

java打印args的内容_解决java main函数中的args数组传值问题

这几天面试中有遇到关于main数组中的args数组传值的问题,一般是从命令提示符中传值,也可以直接在java代码中赋值。 而且这个数组的长度是动态的,根据传值的个数确定数组的长度。 1.从命令提示符中传值 我在桌面新建了一个文本文档重命名为testmain.java,代码如下 public cl…

k8s args和command

首先先看一下busybox.yaml apiVersion: apps/v1 kind: Deployment metadata:name: app spec:replicas: 2template:metadata:labels:name: appspec:containers:- name: appimage: busybox:1.28.4 #内置的linux大多数命令&#xff0c;多用于测试args:- /bin/sh- -c- slee…

java args的用法_Java中args参数数组的用法说明

main方法args参数用于接收用户输入的参数&#xff0c;参数以字符串形式存放在数组中。 这里将传递参数参数的形式分两种&#xff0c;一种是传递普通参数&#xff0c;另一种是传递含有空格的参数。 1、传递普通参数 public class Test { public static void main(String[] args)…

java args什么意思_java中args是什么意思?

在java中&#xff0c;args是arguments的缩写&#xff0c;是指字符串变量名&#xff0c;属于引用变量&#xff0c;名字代号而已&#xff0c;只是一个默认名&#xff0c;可以自己取的&#xff0c;一般都习惯性照写。String[] args是main函数的形式参数&#xff0c;可以用来获取命…

python args函数_Python函数参数*args 和**kwargs的用法

args就是所有参数的数组&#xff0c;kwargs就是当你传入keyvalue是存储的字典&#xff0c;当函数的参数不确定时&#xff0c;可以使用*args 和kwargs&#xff0c;*args 没有key值&#xff0c;kwargs有key值 def fun_var_args(farg, *args): print "arg:", farg for v…