Dubbo ExtensionLoader分析

来源:互联网 发布:经典电影 知乎 编辑:程序博客网 时间:2024/05/16 19:01

ExtensionLoader用法都是这样的形式

ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension()

直接看ServiceConfig的申明变量,

public class ServiceConfig<T> extends AbstractServiceConfig {    private static final long   serialVersionUID = 3033787999037024738L;    private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();        private static final ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();    private static final Map<String, Integer> RANDOM_PORT_MAP = new HashMap<String, Integer>();

就以ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension()为例解析,返回的Protocol 究竟是什么,

以及Exporter<?> exporter = protocol.export(invoker);发生了什么。

先看几个方法

getAdaptiveExtension

从缓存cachedAdaptiveInstance中获取,如果没有调用createAdaptiveExtension获取。

createAdaptiveExtension

调用getAdaptiveExtensionClass得到class,然后newinstance生成对象。

getAdaptiveExtensionClass

先调用一下getExtensionClasses方法,然后如果cachedAdaptiveClass不为空就用这个class,否则使用createAdaptiveExtensionClass方法

cachedAdaptiveClass的设置看下面的loadExtensionClasses方法,这个方法的调用顺序是getExtensionClasses-》getExtensionClasses-》loadExtensionClasses

getExtensionClasses

从缓存cachedClasses获取classes,如果为空则调用loadExtensionClasses方法加载

loadExtensionClasses

获取Protocol接口的SPI注解,然后将cachedDefaultName设为SPI注解的value

@SPI("dubbo")
public interface Protocol

然后在读取本地文件配置的class信息

private static final String SERVICES_DIRECTORY = "META-INF/services/";
private static final String DUBBO_DIRECTORY = "META-INF/dubbo/";
private static final String DUBBO_INTERNAL_DIRECTORY = DUBBO_DIRECTORY + "internal/";

具体根据什么条件选择,暂时没有看,我这里返回了7个,如下,但是getAdaptiveExtensionClass方法并没有使用这个返回值

其中如果这些文件中的类如果带有Adaptive注解,会把cachedAdaptiveClass设置为这个class,默认是都没有带这个注解的


createAdaptiveExtensionClass

默认情况下,第一次都会使用这个方法返回的class,这个方法使用了createAdaptiveExtensionClassCode方法生成一个string描述的对象,

code中包含了需要生成的对象的信息

createAdaptiveExtensionClassCode

完全就是用stringbuilder拼接一个对象,66666

codeBuidler.append("package " + type.getPackage().getName() + ";");
codeBuidler.append("\nimport " + ExtensionLoader.class.getName() + ";");
codeBuidler.append("\npublic class " + type.getSimpleName() + "$Adpative" + " implements " + type.getCanonicalName() + " {")

这三行等于

package com.alibaba.dubbo.rpc;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
public class Protocol$Adpative implements com.alibaba.dubbo.rpc.Protocol {

然后下面一大堆,不说了,结果就是

对于protocol

package com.alibaba.dubbo.rpc;import com.alibaba.dubbo.common.extension.ExtensionLoader;public class Protocol$Adpative implements com.alibaba.dubbo.rpc.Protocol {public void destroy() {throw new UnsupportedOperationException("method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");}public int getDefaultPort() {throw new UnsupportedOperationException("method public abstract int com.alibaba.dubbo.rpc.Protocol.getDefaultPort() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");}public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.Invoker {if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");if (arg0.getUrl() == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");com.alibaba.dubbo.common.URL url = arg0.getUrl();String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);return extension.export(arg0);}public com.alibaba.dubbo.rpc.Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1) throws java.lang.Class {if (arg1 == null) throw new IllegalArgumentException("url == null");com.alibaba.dubbo.common.URL url = arg1;String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);return extension.refer(arg0, arg1);}}

类似的对于ProxyFactory

package com.alibaba.dubbo.rpc;import com.alibaba.dubbo.common.extension.ExtensionLoader;public class ProxyFactory$Adpative implements com.alibaba.dubbo.rpc.ProxyFactory {public java.lang.Object getProxy(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.Invoker {if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");if (arg0.getUrl() == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");com.alibaba.dubbo.common.URL url = arg0.getUrl();String extName = url.getParameter("proxy", "javassist");if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);return extension.getProxy(arg0);}public com.alibaba.dubbo.rpc.Invoker getInvoker(java.lang.Object arg0, java.lang.Class arg1, com.alibaba.dubbo.common.URL arg2) throws java.lang.Object {if (arg2 == null) throw new IllegalArgumentException("url == null");com.alibaba.dubbo.common.URL url = arg2;String extName = url.getParameter("proxy", "javassist");if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])");com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName);return extension.getInvoker(arg0, arg1, arg2);}}

对于registryfactory

package com.alibaba.dubbo.registry;import com.alibaba.dubbo.common.extension.ExtensionLoader;public class RegistryFactory$Adpative implements com.alibaba.dubbo.registry.RegistryFactory {public com.alibaba.dubbo.registry.Registry getRegistry(com.alibaba.dubbo.common.URL arg0) {if (arg0 == null) throw new IllegalArgumentException("url == null");com.alibaba.dubbo.common.URL url = arg0;String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.registry.RegistryFactory) name from url(" + url.toString() + ") use keys([protocol])");com.alibaba.dubbo.registry.RegistryFactory extension = (com.alibaba.dubbo.registry.RegistryFactory)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.registry.RegistryFactory.class).getExtension(extName);return extension.getRegistry(arg0);}}

对于cluster

package com.alibaba.dubbo.rpc.cluster;import com.alibaba.dubbo.common.extension.ExtensionLoader;public class Cluster$Adpative implements com.alibaba.dubbo.rpc.cluster.Cluster {public com.alibaba.dubbo.rpc.Invoker join(com.alibaba.dubbo.rpc.cluster.Directory arg0) throws com.alibaba.dubbo.rpc.cluster.Directory {if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.cluster.Directory argument == null");if (arg0.getUrl() == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.cluster.Directory argument getUrl() == null");com.alibaba.dubbo.common.URL url = arg0.getUrl();String extName = url.getParameter("cluster", "failover");if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.cluster.Cluster) name from url(" + url.toString() + ") use keys([cluster])");com.alibaba.dubbo.rpc.cluster.Cluster extension = (com.alibaba.dubbo.rpc.cluster.Cluster)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.cluster.Cluster.class).getExtension(extName);return extension.join(arg0);}}


写到这里返回的Protocol是什么已经知道了,就是自己生成字节码然后反射生成的,

生成之后查看export方法发现获取了一个Protocol,然后在调用这个Protocol的export方法,

ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);

String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );

url是从arg0获取的 arg0是Invoker类型,关于Invoker请看http://blog.csdn.net/u011686226/article/details/53787477,

从Invoker的url中获取protocol类型,如果没有默认是dubbo,我这里返回的是registry。

然后调用getExtension -》createExtension,返回的的是RegistryProtocol。

RegistryProtocol的export注册服务。

可以发现所有的XXX$Adpative都是动态生成的,然后调用他的方法还会根据不同的参数生成一个XXX对象,真正的调用时这个XXX对象。


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我初一不想读书怎么办 初中孩子不爱学习怎么办 初一就不想读书怎么办 孩子懒得写作业怎么办 初中学生讨厌学习怎么办? 小学不写作业怎么办 幼儿园小朋友不愿意上学怎么办 幼儿园孩子不愿意上学怎么办 宝宝不愿意上幼儿园怎么办 孩子不爱上幼儿园怎么办 宝宝不爱上幼儿园怎么办 宝宝不爱去幼儿园怎么办 幼儿园宝宝不爱写字怎么办 小孩贪玩不爱学习怎么办 老师对幼儿不好怎么办 小孩不愿写作业怎么办 小孩怕老师厌学怎么办 幼儿园怕老师厌学怎么办 孩子很怕老师怎么办 孩子怕外教老师怎么办 家长打老师老师怎么办 被学生骂了怎么办 老师经常打孩子怎么办 老师每天打孩子怎么办 小孩不想去幼儿园怎么办 宝宝不想上幼儿园怎么办 小孩不爱学英语怎么办 孩子抵触学英语怎么办 初三了英语不好怎么办 孩子入园焦虑怎么办 家长总是说孩子怎么办 幼师打了小朋友怎么办 幼儿园老师欺负孩子怎么办 被老师冷落怎么办豆瓣 不满老师对孩子怎么办 老师总找茬孩子 怎么办 老师总针对孩子怎么办 老师看你不舒服怎么办 高中孩子不爱学习怎么办 孩子太倔不听话怎么办 老师老说孩子怎么办