美文网首页
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