美文网首页
Dubbo ExtensionLoader.getAdaptiv

Dubbo ExtensionLoader.getAdaptiv

作者: 王兴岭 | 来源:发表于2020-06-08 17:14 被阅读0次

Dubbo Version: 2.7.7

@SPI
public interface RouterFactory {

    /**
     * Create router.
     * Since 2.7.0, most of the time, we will not use @Adaptive feature, so it's kept only for compatibility.
     *
     * @param url url
     * @return router instance
     */
    @Adaptive("protocol")
    Router getRouter(URL url);
}

@Adaptive注解是放在方法上面的,而且value是protocol,表示在调用方法的时候根据URL的protocol动态加载所需RouterFactory并创建Router

public class AdapteExtendsionTest {
 private static final RouterFactory ROUTER_FACTORY = ExtensionLoader.getExtensionLoader(RouterFactory.class)
     .getAdaptiveExtension();

 public static void main(String[] args) {
   Router router = ROUTER_FACTORY.getRouter(URL.valueOf(
       "condition://0.0.0.0/com.leimo.demo.DemoService?category=routers&dynamic=false&enabled=true&force=true&group=test&name=null&priority=0&router=condition&rule=host+%3D+4.3.2.1+%26+host+%21%3D+1.2.3.4+%3D%3E+false&runtime=false&version=1.0"));
   System.out.println(router.getClass().getName());
 }
}

ExtensionLoader.getExtensionLoader(RouterFactory.class).getAdaptiveExtension()

本质就是动态拼接java类字符串,然后用javassist动态编译成class
拼接生成的类如下

package org.apache.dubbo.rpc.cluster;
import org.apache.dubbo.common.extension.ExtensionLoader;
public class RouterFactory$Adaptive implements org.apache.dubbo.rpc.cluster.RouterFactory {
public org.apache.dubbo.rpc.cluster.Router getRouter(org.apache.dubbo.common.URL arg0)  {
if (arg0 == null) throw new IllegalArgumentException("url == null");
org.apache.dubbo.common.URL url = arg0;
String extName = url.getProtocol();
if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.cluster.RouterFactory) name from url (" + url.toString() + ") use keys([protocol])");
org.apache.dubbo.rpc.cluster.RouterFactory extension = (org.apache.dubbo.rpc.cluster.RouterFactory)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.cluster.RouterFactory.class).getExtension(extName);
return extension.getRouter(arg0);
}
}

当调用接口的getRouter方法时,底层调用的是生成的RouterFactory$AdaptivegetRouter方法,方法逻辑很简单
就是获取URL的protocol,我们测试代码使用的url的protocol是condition,所以extNamecondition,
RouterFactory SPI文件

file=org.apache.dubbo.rpc.cluster.router.file.FileRouterFactory
script=org.apache.dubbo.rpc.cluster.router.script.ScriptRouterFactory
condition=org.apache.dubbo.rpc.cluster.router.condition.ConditionRouterFactory
service=org.apache.dubbo.rpc.cluster.router.condition.config.ServiceRouterFactory
app=org.apache.dubbo.rpc.cluster.router.condition.config.AppRouterFactory
tag=org.apache.dubbo.rpc.cluster.router.tag.TagRouterFactory
mock=org.apache.dubbo.rpc.cluster.router.mock.MockRouterFactory

所以加载的是ConditionRouterFactory
参考文章:
自适应拓展机制

相关文章

网友评论

      本文标题:Dubbo ExtensionLoader.getAdaptiv

      本文链接:https://www.haomeiwen.com/subject/wiirtktx.html