Dubbo源码解读之动态代理

前言

或许我们已悉知Java的动态代理的方式:jdk——通过接口中的方法名,在动态生成的代理类中调用业务实现类的同名方法;cglib——通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理。dubbo在沿用java的jdk方式外,还采取了javassist方式——通过字节码生成代替反射。

Dubbo代理概览

类图(这里只包括我们比较常用的代理类)
image

从类图我们可以看出Dubbo代理工厂主要实现了JavassistProxyFactory和JdkProxyFactory。

具体实现

我们先来看看ProxyFactory接口

@SPI("javassist")
public interface ProxyFactory {

    /**
     * create proxy.
     *
     * @param invoker
     * @return proxy
     */
    @Adaptive({Constants.PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker) throws RpcException;

    /**
     * create proxy.
     *
     * @param invoker
     * @return proxy
     */
    @Adaptive({Constants.PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException;

    /**
     * create invoker.
     *
     * @param <T>
     * @param proxy
     * @param type
     * @param url
     * @return invoker
     */
    @Adaptive({Constants.PROXY_KEY})
    <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;

}

@SPI(“javassist”)注解表示Dubbo默认使用的代理模式,对应后面将会讲到的JavassistProxyFactory。

@Adaptive({Constants.PROXY_KEY})配合@SPI一起使用,其中{Constants.PROXY_KEY}匹配请求url中参数key值,在ExtensionLoader动态加载扩展进行相应匹配。其详细讲解可参考博文https://blog.csdn.net/matthew_zhang/article/details/68966051

ProxyFactory接口有三个方法声明:

  • T getProxy(Invoker invoker):获取代理对象方法接口。
  • T getProxy(Invoker invoker, boolean generic):作用与前一个接口相同,多了一个generic参数,这个参数在dubbo:reference中配置,表示是否缺省泛化接口。如果为泛化接口,将返回GenericService,此时消费者可用如下方式调用。
GenericService demoService = (GenericService) context.getBean("demoService");

Object result = demoService.$invoke("getPermissions", new String[] { "java.lang.Long" }, new Object[]{ 1L });
  • Invoker getInvoker(T proxy, Class type, URL url):获取调用者方法接口。

继续看AbstractProxyFactory抽象类

public abstract class AbstractProxyFactory implements ProxyFactory {

    @Override
    public <T> T getProxy(Invoker<T> invoker) throws RpcException {
        return getProxy(invoker, false);
    }

    @Override
    public <T> T getProxy(Invoker&l
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 回答:Dubbo的调用流程主要包括:服务提供方、服务消费方和注册中心三部分组成。其中,服务提供方向注册中心注册服务,服务消费方通过注册中心发现服务并向服务提供方发起调用;服务提供方收到调用请求后,通过调用服务提供者实现服务,并将结果返回给服务消费方。可以参考以下解读:http://www.sohu.com/a/242295322_465833。 ### 回答2: Dubbo的调用流程分为三个阶段:服务导出、服务引用和远程调用。下面我将结合解读这三个阶段的具体流程。 首先是服务导出阶段。当服务提供者启动时,Dubbo会解析@Service注解,生成ServiceBean对象。然后,Dubbo会调用Protocol的export方法,将ServiceBean暴露成一个Invoker对象,该对象持有ServiceBean的引用和一系列的过滤器链。接着,Dubbo会通过Exporter对象,将Invoker注册到注册中心。最后,Dubbo会根据配置选择合适的Server实现,启动Server并监听服务端口。 接下来是服务引用阶段。当服务消费者启动时,Dubbo会解析@Reference注解,生成ReferenceBean对象。然后,Dubbo会调用ReferenceConfig的get方法,根据配置从注册中心获取服务提供者的Invoker对象。接着,Dubbo会通过Protocol的refer方法,将Invoker封装成一个代理对象,并返回给业务逻辑,实现远程调用。 最后是远程调用阶段。当业务代码调用代理对象的方法时,Dubbo会通过Invocation对象封装方法调用的相关信息。然后,Dubbo会根据服务的URL信息选择合适的InvocationHandler,发起远程调用。在InvocationHandler中,Dubbo会对请求进行编码、协议适配和消息传输,最终将请求发送给服务提供者。服务提供者接收到请求后,会根据请求内容执行相应的服务逻辑,并返回结果。最后,Dubbo会将结果进行解码、协议适配和消息传输,将结果返回给服务消费者。 通过解读可以看出,Dubbo的调用流程主要包括服务导出、服务引用和远程调用三个阶段,并且每个阶段都有一系列的类和方法来协调和处理相应的任务。这样的设计使得Dubbo具备了高度的扩展性和灵活性,能够支持不同的协议和中间件,并提供了一系列的配置选项,满足不同场景下的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值