彩色科技|Dubbo自适应扩展机制( 三 )

前面提到过 , Protocol是一个比较特殊的接口 , Adaptive注解里没有指定Key , 因而没法通过URL携带的参数获取具体的实现类 。 从上面处理过后的内容来看 , 可以看到 , 对于Protocol接口直接使用的URL的protocol属性字段的值来进行判断的 。
如下例子是在Adaptive里有提供key的实现处理过后的内容:
public java.lang.String sayHello(org.apache.dubbo.common.URL arg0) {if (arg0 == null) {throw new IllegalArgumentException("url == null");}org.apache.dubbo.common.URL url = arg0;String extName = url.getParameter("keyA", "dobbo");if (extName == null) {throw new IllegalStateException("Failed to get extension (cn.demo.spi.Factory) name from url (" + url.toString() + ") use keys([keyA])");}cn.demo.spi.Factory extension = (cn.demo.spi.Factory) ExtensionLoader.getExtensionLoader(cn.demo.spi.Factory.class).getExtension(extName);return extension.sayHello(arg0);}可以发现这种情况直接使用的URL的getParameter方法从携带的参数中获取对应的值 。
通过查看AdaptiveClassCodeGenerator的实现可以发现该类的generateExtNameAssignment里对protocol做了特殊的判断 。 AdaptiveClassCodeGenerator完成了代理类内容的创建 , 大概过程为:根据原接口定义(type) , 包装出根据URL参数动态调用getExtension方法的实现类 , 然后将动作实际委托给了ExtensionLoader.getExtensionLoader(type).getExtension(extName);方法 。 其中extName为方法上的Adaptive注解指定的key的对应值 , 获取过程为:

  1. 如果Adaptive注解配置的key为空 , 则使用类名作为扩展名
  2. 如果扩展名为protocol , 则从URL的protocol里获取对应的值
  3. 如果扩展名不为protocol , 且方法参数里有org.apache.dubbo.rpc.Invocation , 则从URL.getMethodParameter里获取
  4. 以上都没有则直接从URL.getParameter中获取 。
Protocol接口由于没有在Adaptive注解里指定key , 则会使用类名protocol作为默认的扩展名 , 从而命中第2条规则 。
【彩色科技|Dubbo自适应扩展机制】通过自适应扩展机制 , Dubbo框架的各层的核心实现都是基于接口的 , 而将具体的实现下放到插件中 。 根据加载的插件不同 , 各层能够选择适合的实现而不会影响核心的逻辑流程 。 如Protocol接口 , 表示通信协议 , 可选的实现包括dubbo、rmi、http等 。
彩色科技|Dubbo自适应扩展机制