动态代理模式newProxyInstance及invoke方法参数详解

动态代理概述:

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方法中就可以实现对所有方法的统一包装了。

  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值