动态代理概述:

Java提供的动态代理类Proxy:

Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.
代理类Proxy提供静态方法用于创建动态代理子类和对象。它也是所有通过这些静态方法所创建的动态代理子类的父类。

其中一个最常用的静态方法就是:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)
Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.
返回一个实现了所有指定接口的代理子类对象,该对象将方法调用分派给指定的调用处理器。



ClassLoader :被代理类的类加载器,方法内部会调用这个类加载器来获取继承Proxy类的子类字节码文件对象Class,加载的同时该子类也实现所有指定的接口。

Class<?>[] interfaces: 被代理类 的所有实现接口的Class对象,在方法内部会克隆一份加载进Proxy字节码对象中。

表示实现Proxy类实现所有指定接口。

InvocationHandler接口:(调用处理器)

InvocationHandler is the interface implemented by the invocation handler of a proxy instance.
调用处理器是一个通过 代理对象的调用处理器(Handler实现类中的invoke) 来实现的接口
Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.
每一个代理对象都有相关联的调用处理器。 当一个方法伴随所属代理对象被调用,这个方法调用就会被编码转移为调用处理器中的相应扩展方法调用。

​ 总的来讲,每一个proxy代理对象都有一个实现InvocationHandler接口的实现类Handler,这个实现类中的invoke方法就是proxy代理对象的实际调用处理器,在这个invoke方法体中,有所有 被代理对象 的方法逻辑实现和扩展。

​ 每当代理对象proxy被反射机制用于调用其方法时,这个方法调用就自动转移为Handler类里invoke方法体中的对应扩展方法调用。

InvocationHandler这个接口的唯一一个方法 invoke 方法:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable
proxy:代理对象,只是反射机制调用方法的需要
method: proxy被反射机制用于调用的方法对象
args:调用方法的参数列表

动态代理实现:

这里面首先想要做到动态代理,必须先实现这个InvocationHandler接口,然后我们主要看getProxy方法,参数是需要被代理的对象Singer

​ 方法里面有一个Proxy类,这个Proxy类提供了很多方法,这里我们用的是newProxyInstance方法,它有三个参数,第一个是被代理类的类构造器,第二个指的是被代理类的接口,也就是Singer的接口,第三个是实现这个代理过程的类,就是本类。具体的来说,这个方法执行了下面三步:

​ 1.用ClassLoader加载器生成一个实现了参数interfaces里所有接口且继承了Proxy的代理类的字节码对象。

​ 2.使用Proxy的构造函数 Proxy(InvocationHandler h)来创造一个代理类的实例,将我们自定义的InvocationHandler子类传入。

​ 3.返回这个代理类实例对象,因为我们构造的代理类实现了interfaces(也就是我们程序中传入的Singer.class.getInterfaces())里的所有接口,因此返回的代理类可以强转成Star类型来调用接口中定义的方法。

而在调用每个代理类每个方法的时候,都用反射去调InvocationHandler实现类的invoke方法(也就是我们自定义的AutoProxy重写的invoke方法),用参数传递了代理类实例、接口方法、调用参数列表,这样我们在重写的invoke方法中就可以实现对所有方法的统一包装了。

动态代理模式newProxyInstance及invoke方法参数详解相关推荐

  1. java中的invoke方法_详解Java中Method的Invoke方法

    在写代码的时候,发现从父类class通过getDeclaredMethod获取的Method可以调用子类的对象,而子类改写了这个方法,从子类class通过getDeclaredMethod也能获取到M ...

  2. python文件对象提供了3个读方法、分别是-Python读写文件模式和文件对象方法实例详解...

    本文实例讲述了Python读写文件模式和文件对象方法.分享给大家供大家参考,具体如下: 一. 读写文件模式 利用open() 读写文件时,将会返回一个 file 对象,其基本语法格式如: open ( ...

  3. 动态库装载及 dlsym的RTLD_NEXT参数详解

    在看公司spp框架代码的时候发现了如下一段宏定义,其中的dlsym函数及其RTLD_NEXT参数的含义不是很明白,于是网上搜了下这里做个记录. #define mt_hook_syscall(name ...

  4. java recordset_adodb.recordset.open(rs.open)方法参数详解

    ADO Recordset 对象 ADO Recordset 对象用于容纳一个来自数据库表的记录集.一个 Recordset 对象由记录和列(字段)组成. 在 ADO 中,此对象是最重要且最常用于对数 ...

  5. canvas的drawImage方法参数详解

    引言: canvas很有意思的一项特性就是图像操作能力.可以用于动态的图像合成或者作为图形的背景,以及游戏界面(Sprites)等等.浏览器支持的任意格式的外部图片都可以使用,比如PNG.GIF或者J ...

  6. intent.putExtra()方法参数详解

    [putExtra("A",B)中,AB为键值对,第一个参数为键名,第二个参数为键对应的值.顺便提一下,如果想取出Intent对象中的这些值,需要在你的另一个Activity中用g ...

  7. 一键进入dfu模式软件_dfu模式是什么 dfu模式介绍及进入方法【详解】

    dfu模式是什么意思?怎么进入dfu模式?dfu模式 即iPhone固件的强制升降级模式(工厂模式),它一般是在iPhone无法开机,iTunes不能识别时或者降级越狱引导时,才会用得到. 注意与恢复 ...

  8. JQuery中$.ajax()方法参数详解(转)

    url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...

  9. Assert.assertEquals()方法参数详解

    junit.framework包下的Assert提供了多个断言方法. 主用于比较测试传递进去的两个参数. Assert.assertEquals();及其重载方法: 1. 如果两者一致, 程序继续往下 ...

最新文章

  1. 2.monotouch 控件的使用
  2. java重定向设置header_在Java中重定向请求时如何传递HTTP头中的数据
  3. mysql将一个字符转换成多个字符_将分隔的字符串转换为mysql中的多个值
  4. CodeForces - 1535C Unstable String(思维)
  5. 判断输入的整数是否为素数_C语言 | 判断是否素数
  6. COOKIE伪造登录网站后台
  7. Python time datetime常用时间处理方法
  8. python函数示例_PHP closeir()函数与示例
  9. conv2d的输入_pytorch1.0中torch.nn.Conv2d用法详解
  10. 月薪3K与月薪3万的程序员,距离是怎么拉开的?
  11. 连通子图什么意思_一道物理竞赛题揭开“希罗喷泉”的神秘面纱,到底什么物理原理?...
  12. [Java] 蓝桥杯ALGO-13 算法训练 拦截导弹
  13. Linux设备驱动之字符设备(一)
  14. java打印unicode,在Java中打印Unicode字符
  15. 2021-2022-1 线性代数知识点总结
  16. 制作maven模板框架
  17. 光学字符识别引擎 tesseract-ocr 简介
  18. 微信小程序-WXML-template模板
  19. 炬芯平台SPP私有协议调试
  20. 泽塔云:用超融合撑起软件定义数据中心的梦想

热门文章

  1. 【ReID】【代码注释】HA-CNN的网络模型 deep-person-reid/models/HACNN.py
  2. 北邮计算机学院英语面试,北京邮电大学2021计算机与软件考研数据分析
  3. webmagic+selenium模拟浏览器启动(动态网页爬取方法之一的第一步)
  4. S如何获取扫描枪扫描的数据
  5. Android实现背景图下拉回弹效果
  6. 计算机系大二学期计划范文,大二学习计划
  7. linux分屏方式显示2015,Linux下的分屏显示
  8. 混合特征目标选择用于基于BCI的二维光标控制
  9. 求乘法逆元c语言版,C语言实现求乘法逆元
  10. 小型图像数据集效果优化:使用预训练的CNN