静态代理

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实现代码也可以通过工具自动生成,不过这样让框架使用起来更加的复杂。


直抒胸臆
39 声望3 粉丝

程序员里面羽毛球打的最好的