关于dubbo扩展点的一点分析
扩展点能力
- 能load class,这个class除了顶层接口class(在ExtensionLoader中对应type字段),还能load各实现类的class。
- 能创建instance。
- 能指定这个顶层接口的默认实现类的beanName。做法参见SPI注解部分。
- 能把创建出来的instance的字段注入。set开头的且有一个参数且是public的,注入。
- 能adaptive。根据url上对该接口配置的实现类,将该接口的事情交给这个实现类去做(我更多的理解成委托)。此能力采用代码生成再编译的方式。代码生成示例可以参见adaptive类代码示例。 adaptive只会生成一个adaptive实现类。生成代码的逻辑在com.alibaba.dubbo.common.extension.ExtensionLoader.createAdaptiveExtensionClassCode()
- 能wrapper。wrapper是指这个顶层接口的实现类的构造函数的入参是这个顶层接口类型。那么这个实现类称之为wrapper类,可以有多个,构建instance时不分多个之间的顺序。因为用来给构造函数传参的instance是这个顶层类的默认实现。比如com.alibaba.dubbo.rpc.Protocol接口,有实现类 com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol beanName是injvm,QosProtocolWrapper、ProtocolListenerWrapper、ProtocolFilterWrapper是其三个wrapper类。创建warpper instance的代码逻辑在com.alibaba.dubbo.common.extension.ExtensionLoader.createExtension(String)中。
- 能active。实现类加了Activate注解的。在ExtensionLoader.getActivateExtension时会根据当前的url(配置信息)中值来匹配Activate注解中指定的值是否能match,能match的表示是activate,意思是命中的。在过滤器扩展点中用到。比如这个过滤器是给CONSUMER group用。示例有ExceptionFilter等。同时该注解还能支持order属性来定义bean的顺序。
扩展点使用
配置文件相关
配置文件放在哪里?
- META-INF/dubbo/internal/配置文件
- META-INF/dubbo/配置文件
- META-INF/services/配置文件
配置文件名是顶层接口全限定名,比如:com.alibaba.dubbo.rpc.Protocol
配置文件中内容:
一行是一个实现类的定义,大致是
beanName=实现类的class的全限定名,这个后面还可以接上#xxx(这个能力实际使用少)。beanName=这部分不是必须的。可以仅仅写实现类的全限定名。
注解相关
SPI
SPI注解用在顶层接口上,其值表示这个接口的默认实现类的beanName,也即是说指定一个顶层接口的默认实现通过SPI注解加载顶层接口上指定即可。
Adaptive
Adaptive注解用在顶层接口或者接口的方法上,其表示这个接口或者这个方法需要有adaptive的类委托完成,未加注解的会生成不支持的操作的方式实现。
Activate
Activate注解用在实现类上,其表示实现类在rpc时根据url参数中以及注解中指定的key 目标value是否能匹配来决定此bean是否被选中(一般用在过滤器的命中判断上)。
生成的代码
adaptive类代码示例
package com.alibaba.dubbo.registry;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
public class RegistryFactory$Adaptive 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);
}
}
package com.alibaba.dubbo.rpc.cluster;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
public class Cluster$Adaptive 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.RpcException {
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);
}
}
杂项
查找所有的dubbo扩展点形式的配置文件
find ./ -type f -name "com.alibaba.dubbo*"|grep -v "/target/"|grep -v "/bin/"|grep -v "/test/"
另:
关于代理模式,dubbo未实现通用的,只是rpc语义实现里rpc调用的代理,借助扩展点机器加动态代理完成。
具体其顶层接口是com.alibaba.dubbo.rpc.ProxyFactory。用在比如将EchoService编织进每次RPC调用中。
关于dubbo扩展点的一点分析的更多相关文章
- Dubbo系列讲解之扩展点实现原理分析【2万字分享】
Apache Dubbo 是一款微服务开发框架,它提供了 RPC通信 与 微服务治理 两大关键能力.这意味着,使用 Dubbo 开发的微服务,将具备相互之间的远程发现与通信能力, 同时利用 Dubbo ...
- 从Spring容器的角度理解Dubbo扩展点的加载时机
对于Dubbo提供的扩展点,主程序执行的过程中并没有显示调用加载的过程,无论是自激活的Filter还是自适应的ThreadPool.那么这样的扩展点在程序运行的哪个节点调用的呢?跟踪之前性能监控扩展点 ...
- App store 应用审核由于 IPv6 网络问题被拒的一点分析
App store 应用审核由于 IPv6 网络问题被拒的一点分析 六月以后陆续有一些软件提交市场的时候被拒了,症状基本就是无法登陆啥的.我们公司的应用也未能幸免. 很多同学也想了不少办法,申诉. ...
- Linq分组操作之GroupBy,GroupJoin扩展方法源码分析
Linq分组操作之GroupBy,GroupJoin扩展方法源码分析 一. GroupBy 解释: 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值. 查询表达式: var ...
- Dubbo扩展点应用之二负载均衡
负载均衡其本质就是将请求分摊到多个操作单元上进行,从而共同完成工作任务.其策略主要用于客户端春常在多个提供者时根据算法选择某个提供者.在集群负载均衡时,Dubbo提供了多种均衡策略(包括随机.轮询.最 ...
- Dubbo 扩展点加载机制:从 Java SPI 到 Dubbo SPI
SPI 全称为 Service Provider Interface,是一种服务发现机制.当程序运行调用接口时,会根据配置文件或默认规则信息加载对应的实现类.所以在程序中并没有直接指定使用接口的哪个实 ...
- Dubbo SPI 机制源码分析(基于2.7.7)
Dubbo SPI 机制涉及到 @SPI.@Adaptive.@Activate 三个注解,ExtensionLoader 作为 Dubbo SPI 机制的核心负责加载和管理扩展点及其实现.本文以 E ...
- Dubbo的优雅下线原理分析
文/朱季谦 Dubbo如何实现优雅下线? 这个问题困扰了我一阵,既然有优雅下线这种说法,那么,是否有非优雅下线的说法呢? 这,还真有. 可以从linux进程关闭说起,其实,我们经常使用到杀进程的指令背 ...
- 2048游戏分析、讨论与扩展 - Part I - 游戏分析与讨论
2048这个游戏从刚出開始就风靡整个世界. 本技术博客的目的是想对2048涉及到相关的全部问题进行仔细的分析与讨论,得到一些大家能够接受而且理解的结果. 在这基础上,扩展2048的游戏性,使其变得更好 ...
随机推荐
- Oracle创建自动增长列
前言: Oracle中不像SQL Server在创建表的时候使用identity(1001,1)来创建自动增长列,而是需要结合序列(Sequences)和触发器(Triggers)来实现 创建测试表 ...
- 基于Python爬虫采集天气网实时信息
相信小伙伴们都知道今冬以来范围最广.持续时间最长.影响最重的一场低温雨雪冰冻天气过程正在进行中.预计,今天安徽.江苏.浙江.湖北.湖南等地有暴雪,局地大暴雪,新增积雪深度4-8厘米,局地可达10- ...
- http与https的简单比较
一.概念 1.HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减 ...
- pandas巩固
导包 import pandas as pd 设置输出结果列对齐 pd.set_option('display.unicode.ambiguous_as_wide',True) pd.set_opti ...
- Django学习路32_创建管理员及内容补充+前面内容复习
创建管理员 python manage.py createsuperuser 数据库属性命名限制 1.不能是python的保留关键字 2.不允许使用连续的下划线,这是由django的查询方式决定的 ...
- Python os.tmpnam() 方法
概述 os.tmpnam() 方法用于为创建一个临时文件返回一个唯一的路径.高佣联盟 www.cgewang.com 语法 tmpnam()方法语法格式如下: os.tmpnam 参数 无 返回值 返 ...
- PHP fread() 函数
定义和用法 fread() 函数读取打开的文件. 函数会在到达指定长度或读到文件末尾(EOF)时(以先到者为准),停止运行. 该函数返回读取的字符串,如果失败则返回 FALSE. 语法 string ...
- PHP xml_set_default_handler() 函数
定义和用法 xml_set_default_handler() 函数为 XML 解析器建立默认的数据处理器.高佣联盟 www.cgewang.com 该函数规定在只要解析器在 XML 文件中找到数据时 ...
- PHP sha1_file() 函数
实例 计算文本文件 "test.txt" 的 SHA-1 散列: <?php高佣联盟 www.cgewang.com$filename = "test.txt&qu ...
- PHP nl_langinfo() 函数
定义和用法 nl_langinfo() 函数返回指定的本地信息. 注释:该函数无法在 Windows 平台上工作. 提示:与返回所有本地格式化信息的 localeconv() 函数不同,nl_lang ...