乐趣区

java动态代理的理解

静态代理

public class TargetClass{void method1()
}

public class ProxyClass{
    private TargetClass target;
    
    public void method1(){target.method1()
    }
}
  • 代理类持有目标类的引用

动态代理

public interface TargetIntf{void method1();
}

public DynamicProxy implements InvocationHandler{
    @Override
    public Object invoke(Object o, Method method, Object[] args){//do proxy}
}

InvocationHandler handler = new DynamicProxy();
Proxy theProxy = (TargetIntf)Proxy.newInstance(hander.getClass().getClassLoader(), new Class[]{TargetIntf.class}, handler);
theProxy.method1()
  • 要有接口
  • 要实现 InocationHandler
  • 通过 Proxy.newInstance 来生成代理类
  • 通过强转取得目标类的实例

如何理解动态代理

当调用 theProxy 的 method1 时,会触发 handler.invoke 方法的调用,方法 (Method) 和参数都会传递给 invoke 方法,invoke 方法里面想做什么都行。

为什么 Proxy.newInstance 可以强转成 TargetIntf 呢?

Proxy.newInstance 返回的对象实现了 TargetIntf 接口的方法,所以可以强转。

为什么调用 proxy 的 method1 方法会调用到 handler 的 invoke 方法?

Proxy.newInstance 返回的对象组合了 handler,并在 method1 方法的实现逻辑中添加了 handler.invoke 的调用。

Proxy.newInstance 如何动态的实现 TargetIntf 的方法并返回对象实例呢?

动态的生成 class 文件,java 类的信息都是从 class 文件加载进来的,Proxy.newInstance 方法中动态的生成了 class 文件并加载。

动态代理能干嘛?

  • 提供了另外一种实现接口的方式,不用 implements 也能实现接口。
  • 可以用来写框架

试想一下,如果没有动态代理,dubbo 框架如何实现?

动态代理的 dubbo 实现:

  • client 和 server 端都依赖 api 的接口
  • client 端不实现 api 接口,通过动态代理,把 api 接口调用连接到 Invocation.invoke 方法上,在此方法中将对象、方法名、参数等通过网络发送给 server 端
  • server 端实现 api 的接口,把 client 端发送过来的 rpc 调用连接到 api 接口的具体实现上。

没有动态代理的实现:

  • client 和 server 端都依赖 api 接口
  • client 端实现 api 接口,接口的实现逻辑为把对象、方法名、参数等通过网络发送给 server 端
  • server 端实现 api 的接口,把 client 端发送过来的 rpc 调用连接到 api 接口的具体实现上。

有了动态代理,dubbo rpc 中的网络交互部分可以完全写在 dubbo 框架中,对用户来说编程更加方便。
没有动态代理,client 端的 api 实现代码也可以通过工具自动生成,不过这样让框架使用起来更加的复杂。

退出移动版