【Dubbo系列02】动态代理

动态代理是提供一种抽象,将对实例的不同方法的调用重定向到一个统一的处理函数,然后做自定义的逻辑处理,整个过程对于调用者是透明的,并且代理类与业务无关。
被代理的类可以不在本地,动态代理语法提供一种抽象方式,被代理的类可以位于远程主机,这就是RPC框架的实现原理。

一、RPC框架中动态代理的职责

RPC框架需要像调用本地接口一样调用远程接口,也就是上文提到面临的那三个问题。如何组装数据报文,通过网络发送到服务提供方,屏蔽远程接口调用的细节,这就需要通过动态代理来实现。

二、动态代理实现方式

  • jdk动态代理
  • cglib动态代理
  • javassist动态代理
  • ASM字节码
  • javassist字节码
    其中,Spring使用的是jdk和cglib的动态代理,Dubbo默认使用的是javassist动态代理。

三、JDK动态代理

JDK的动态代理只能对接口进行代理。这是因为Java的单继承造成的,JDK生成的动态代理类需要继承java.lang.reflect.Proxy,所以要求只能对接口代理。Spring中是使用JDK动态代理对接口代理,对类代理使用cglib。

JDK动态代理角色

  • 代理接口
    JDK动态代理机制规定给调用者使用的代理类只能是接口

    1
    2
    3
    interface Operation {
    int add(int a, int b);
    }
  • 代理处理器
    统一的处理函数,JDK动态代理约定要实现InvocationHandler接口。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class OperationProxyHandler implements InvocationHandler {
    private Object target;//被代理对象
    // 构造方法保持被代理对象
    public OperationProxyHandler(Object target){
    this.target = target;
    }
    // 统一处理函数
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //使用反射将放到代理到被代理对象上
    return method.invode(target, args)
    }
    }
  • 被代理类
    实际执行工作的类

    1
    2
    3
    4
    5
    6
    class OperationImpl implements Operation {
    @Override
    public int add (int a, int b) {
    return a + b;
    }
    }
  • 创建代理类
    调用者使用的是实现代理接口的代理类,代理类的创建,JDK的动态代理也有相应的api供我们使用

    1
    2
    3
    4
    5
    6
    public static void main(String[] args) {
    Operation op = (Operation) Proxy.newProxyInstance(Operation.class.getClassLoader(), // 加载接口的类加载器
    new Class[]{Operation.class}, // 一组接口
    new MyInvocationHandler(new OperationImpl())); // 自定义的InvocationHandler,持有实现类实例
    System.out.println(op.add(2, 3));
    }

四、总结

JDK动态代理是实现RPC的基础,这里我们了解JDK的动态代理的使用,Dubbo默认是使用javassist动态代理,但都是使用动态代理来实现远程方法调用,只是实现动态代理的方式不同。

相信技术的力量,原创技术文章,感谢您的支持!