您的位置 首页 java

java程序员面试必备知识:java的动态代理

代理模式

在讲动态代理之前,需要了解什么是代理模式,经典的代理模式的uml图相信大家都见过:

代理模式

RealSubject是需要被代理的对象。我们要在RealSubject之外增加一些处理,就增加一个Proxy类,实现Subject接口,在Proxy类里持有RealSubject的实例。

Client的请求全部打到Proxy实例上,由Proxy实例来控制是否将请求转发给RealSubject,或者做额外的处理。

代理模式的优点:对于外界来讲,完全无感知, 耦合性 低。

看一下实例代码:

这里对Integer类做了一层代理。这个类的作用在于,在compareTo请求之上增加了信息的打印输出。

在实际场景中,如果我们需要对多个方法都要做类似的处理,在每个地方都增加同样的代码,就显得有点不够优雅了。这时候,可以使用 java 的动态代理。

常用的动态代理有两种实现方式: JDK CGLIB

JDK动态代理

看名字就可以知道,这种动态代理是JDK本身就支持的,需要借助java. lang .reflect下的接口来实现。

创建代理对象

要想创建一个代理对象,需要使用Proxy类的newProxyInstance方法。

这个方法有三个参数:

  1. 类加载器。作为Java安全模型的一部分,对于系统类和从因特网上下载下来的类,可以使用不同的类加载器。

  2. Class对象数组,每个元素都是需要实现的接口。

  3. 调用处理器。

调用处理器

调用处理器是实现了InvocationHandler接口的类对象。在这个接口中只有一个方法:

动态代理类,需要实现此接口,在接口方法的实现里做代理逻辑的处理。

创建动态代理

创建一个动态代理对象的工作如下:

  1. 获取 RealSubject上的所有接口列表;

  2. 确定要生成的代理类的类名,默认为:com.sun.proxy.$ProxyXXXX ;

  3. 根据需要实现的接口信息,在代码中动态创建 该Proxy类的 字节码

    4 将对应的字节码转换为对应的class 对象;

  4. 创建InvocationHandler 实例handler,用来处理Proxy所有方法调用;

  5. Proxy的class对象以创建的handler对象为参数, 实例化 一个proxy对象。

    接下来我们看一段代码实现:

那如何TraceHandler有什么用呢?

利用TraceHandler可以打印出 二分查找 的查找顺序:

为何 toString 也会被代理

细心的读者会发现,上面的程序执行最后有一行

为什么toString方法也会被代理呢,我们代理的接口里,并没有声明toString的方法呀。

这里有两点我们需要知道:

  • 所有的代理类都扩展于Proxy类;

  • 所有的代理类都覆盖了Object类中的方法toString、equals和 hashCode

    针对上面的第二点,所有对代理类的toString、equals和hashCode的方法调用,都会请求到invoke代理实现上去。所以就出现toString方法也被代理的情况了。

文章来源:智云一二三科技

文章标题:java程序员面试必备知识:java的动态代理

文章地址:https://www.zhihuclub.com/191582.shtml

关于作者: 智云科技

热门文章

网站地图