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 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对象。
- Dubbo ExtensionLoader分析
- Dubbo源码分析(五)ExtensionLoader
- dubbo源码分析-ExtensionLoader发现机制和Adaptive注解应用
- Dubbo ExtensionLoader源码解读
- dubbo spi extensionloader 插件化
- Dubbo源码 SPI实现ExtensionLoader
- Dubbo源码阅读之 ExtensionLoader
- dubbo 1 ExtensionLoader 插件化
- [Dubbo源码剖析]ExtensionLoader机制
- 怎么将dubbo的SPI移植到开源项目中,附dubbo的ExtensionLoader<T> 的实现原理分析
- Dubbo 源码解析系列一 ExtensionLoader
- 第一章 Dubbo风格的SPI-ExtensionLoader
- 从ExtensionLoader看Dubbo插件化
- 从ExtensionLoader看Dubbo插件化
- Dubbo系列-3.扩展核心ExtensionLoader
- dubbo源码解析(一): 扩展点加载(ExtensionLoader)
- 深入dubbo之ExtensionLoader,灵活的扩展点加载机制
- 构造函数线程安全-即dubbo的extensionLoader存在线程安全问题
- mysql Copying to tmp table on disk 影响性能的解决方法
- js模拟HashMap的存储结构-无序版
- memcache学习整理
- java中为什么类名可以直接调用静态方法?
- ehcache详细解析
- Dubbo ExtensionLoader分析
- org.apache.log4j.Logger详解
- sublime Text2 如何配置nodejs
- java常见异常总结
- ORACLE查看并修改最大连接数
- Poj_1011 Sticks(dfs)
- mysqld 已死,但是 subsys 被锁
- echart3.0正负图取数据java代码
- Android stepview 简单使用。