前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java的动态代理与RPC

Java的动态代理与RPC

原创
作者头像
Mark Sun
发布2023-01-29 23:07:56
5851
发布2023-01-29 23:07:56
举报
文章被收录于专栏:Java面试必知必会

背景

RPC大家有一定了解后,在Java开发生态下,动态代理和它有着紧密联系。 如果单拎出动态代理,你一定会有一大堆八股文,它和RPC是什么关系?

一、使用场景

在使用RPC的时候,需要服务方提供interface,在调用方编写业务逻辑时,调用接口的方法,拿到结果。为什么?

RPC会为接口生成一个代理类,调用方在使用过程中,实际运行时该接口被调用会被代理类给拦截到,在代理类中具体实现远程调用逻辑。

这里其实就使用到了动态代理技术,场景描述如下,

通过这种hack手法,用户就不会感知远程调用的细节,实际就和调用本地方法一样。

二、Java动态代理

代码运行环境要求:open Jdk11

代码语言:javascript
复制
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * interface
 */
interface HelloWorld {
    String speak();
}

/**
 * real object
 */
class RealHello {
    public String say() {
        return "i'm RealHello";
    }
}

/**
 * proxy
 */
class JdkProxy implements InvocationHandler {
    private final Object target;

    JdkProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] paramValues) {
        return ((RealHello) target).say();
    }
}

/**
 * TestProxy
 */
public class TestProxy {
    public static void main(String[] args) {
        JdkProxy jdkProxy = new JdkProxy(new RealHello());
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        // save proxy class
        System.setProperty("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");
        // generate proxy object
        HelloWorld test = (HelloWorld) Proxy.newProxyInstance(classLoader, new Class[] {HelloWorld.class}, jdkProxy);
        // invoke proxy
        System.out.println(test.speak());
    }
}

本段代码的含义:HelloWorld接口生成一个代理类,并调用它的speak方法,返回的数据是RealHello的say方法返回值。

三、额外思考

如果没有动态代理那么如何完成方法调用拦截,实现RPC?

显而易见动态不行,就静态。但是静态有一个不好的地方,那就是需要针对性的为每个实现类创建一个代理类,并且需要写序列化、负载均衡、失败重试等等,上线一个 RPC调用的特性从一天可能就变成一周了。

对于RPC增加或修改接口的情况,动态代理无需修改,自适应协议的变化,而静态代理需要重新生成代码覆盖调用方和服务方。

如果是跨语言的类似GRPC的这种要怎么弄呢?对于动态代理,要么是各种reflect逻辑从服务提供方动态获取解析类型和数据,要么就构建一堆的硬编码,可以理解为通过模板动态生成支持适配协议的相关代码,这两个的代表在GRPC中是envoy和grpc-gateway。

小结

动态代理作为在RPC里面的一种应用,虽然只是具体实现技术,但理解了它才能更好的理解RPC里面是如何做到面向接口编程,帮助用户屏蔽RPC调用细节,达到远程调用。

动态代理本身是一种技术框架,在使用时,我们就需要有一个合理的选型,一般从框架生成代理类的速度、代理类字节码的大小、代理类的执行效率、框架的生态是否繁荣等去选择。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 一、使用场景
  • 二、Java动态代理
  • 三、额外思考
  • 小结
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档