dubbo系列七、dubbo @Activate 注解使用和实现解析
时间:2019-12-10
本文章向大家介绍dubbo系列七、dubbo @Activate 注解使用和实现解析,主要包括dubbo系列七、dubbo @Activate 注解使用和实现解析使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、用法
Activate注解表示一个扩展是否被激活(使用),可以放在类定义和方法上,dubbo用它在spi扩展类定义上,表示这个扩展实现激活条件和时机。
@Activate(group = Constants.PROVIDER) public class DrpcServerInterceptor implements Filter{ private final ServerRequestInterceptor serverRequestInterceptor; private final ServerResponseInterceptor serverResponseInterceptor; public DrpcServerInterceptor() { String sendUrl = ZipkinConfig.getProperty(ZipkinConstants.SEND_ADDRESS); Sender sender = OkHttpSender.create(sendUrl); Reporter<zipkin.Span> reporter = AsyncReporter.builder(sender).build(); String application = ZipkinConfig.getProperty(ZipkinConstants.BRAVE_NAME);//RpcContext.getContext().getUrl().getParameter("application"); Brave brave = new Brave.Builder(application).reporter(reporter).build(); this.serverRequestInterceptor = brave.serverRequestInterceptor(); this.serverResponseInterceptor = brave.serverResponseInterceptor(); } 。。。。 }
表示该类只在生产者生效。
二、源码解析
先看下接口定义:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface Activate { /** * Group过滤条件。 * <br /> * 包含{@link ExtensionLoader#getActivateExtension}的group参数给的值,则返回扩展。 * <br /> * 如没有Group设置,则不过滤。 */ String[] group() default {}; /** * Key过滤条件。包含{@link ExtensionLoader#getActivateExtension}的URL的参数Key中有,则返回扩展。 * <p/> * 示例:<br/> * 注解的值 <code>@Activate("cache,validatioin")</code>, * 则{@link ExtensionLoader#getActivateExtension}的URL的参数有<code>cache</code>Key,或是<code>validatioin</code>则返回扩展。 * <br/> * 如没有设置,则不过滤。 */ String[] value() default {}; /** * 排序信息,可以不提供。 */ String[] before() default {}; /** * 排序信息,可以不提供。 */ String[] after() default {}; /** * 排序信息,可以不提供。 */ int order() default 0; }
它有两个设置过滤条件的字段,group,value 都是字符数组。用来指定这个扩展类在什么条件下激活。
下面以com.alibaba.dubbo.rpc.filter接口的几个扩展来说明。
//如MonitorFilter @Activate(group = {Constants.PROVIDER, Constants.CONSUMER}) public class MonitorFilter implements Filter { }
表示如果过滤器使用方(通过group指定)属于Constants.PROVIDER(服务提供方)或者Constants.CONSUMER(服务消费方)就激活使用这个过滤器。
//再看这个扩展 @Activate(group = Constants.PROVIDER, value = Constants.TOKEN_KEY) public class TokenFilter implements Filter { }
表示如果过滤器使用方(通过group指定)属于Constants.PROVIDER(服务提供方)并且 URL中有参数 Constants.TOKEN_KEY(token)时就激活使用这个过滤器。
再看下具体实现:
dubbo在ExtensionLoader类,解析某个接口扩展实现类时,会把所有实现类中有Activate注解的,都先放到一个全局map中。
Activate activate = clazz.getAnnotation(Activate.class); if (activate != null) { //如果有,加入,cachedActivates map 扩展名:实现类class,形式 cachedActivates.put(names[0], activate); }
然后提供了4个方法来具体使用cachedActivates,返回要激活使用的扩展。
/** * This is equivalent to <pre> * getActivateExtension(url, key, null); * </pre> * 在所有的激活中,要使用key 指定的扩展 * @param url url * @param key url parameter key which used to get extension point names * @return extension list which are activated. * @see #getActivateExtension(com.alibaba.dubbo.common.URL, String, String) */ public List<T> getActivateExtension(URL url, String key) /** * This is equivalent to <pre> * getActivateExtension(url, url.getParameter(key).split(","), null); * </pre> * 在所有的激活中,要指定的group 外加 使用key 指定的扩展 * @param url url * @param key url parameter key which used to get extension point names * @param group group * @return extension list which are activated. * @see #getActivateExtension(com.alibaba.dubbo.common.URL, String[], String) */ public List<T> getActivateExtension(URL url, String key, String group) /** * This is equivalent to <pre> * getActivateExtension(url, values, null); * </pre> * 在所有的激活中 values指定的扩展 * @param url url * @param values extension point names * @return extension list which are activated * @see #getActivateExtension(com.alibaba.dubbo.common.URL, String[], String) */ public List<T> getActivateExtension(URL url, String[] values) //最后其实都有下面方法实现 /** * Get activate extensions. * 加载active扩展 * @param url url * @param values extension point names * @param group group * @return extension list which are activated * @see com.alibaba.dubbo.common.extension.Activate */ public List<T> getActivateExtension(URL url, String[] values, String group) { List<T> exts = new ArrayList<T>(); List<String> names = values == null ? new ArrayList<String>(0) : Arrays.asList(values); if (!names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) { getExtensionClasses(); //cachedActivates里放的map结构 接口实现扩展名:其上的Activate对象 for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {//遍历所有Activate注解对象 String name = entry.getKey();//spi 扩展名 Activate activate = entry.getValue(); if (isMatchGroup(group, activate.group())) {//如果有group匹配 T ext = getExtension(name);//加在扩展类 //name不在 values 指定之列,并且没排除name,并且activate的value 在url有对应参数,就算激活 if (!names.contains(name) && !names.contains(Constants.REMOVE_VALUE_PREFIX + name) && isActive(activate, url)) { // exts.add(ext); } } } //排序Activate 具体实现在ActivateComparator里,实现了Comparator 接口compare方法 Collections.sort(exts, ActivateComparator.COMPARATOR); } List<T> usrs = new ArrayList<T>(); for (int i = 0; i < names.size(); i++) { String name = names.get(i); if (!name.startsWith(Constants.REMOVE_VALUE_PREFIX) && !names.contains(Constants.REMOVE_VALUE_PREFIX + name)) { //遍历所有没有排除的扩展名 if (Constants.DEFAULT_KEY.equals(name)) { if (usrs.size() > 0) { exts.addAll(0, usrs); usrs.clear(); } } else { //通过扩展名,加载扩展添加到结果集 T ext = getExtension(name); usrs.add(ext); } } } if (usrs.size() > 0) { exts.addAll(usrs); } //返回符合条件的激活扩展 return exts; }
原文地址:https://www.cnblogs.com/ceshi2016/p/12016425.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PostgreSQL drop table 空间不释放的问题解决
- R语言预测人口死亡率:用李·卡特模型、非线性模型进行平滑估计
- Dockerfile 指令
- Docker 构建容器Tomcat+Nginx+MySQL
- 三种动态控制SAP CRM WebClient UI assignment block显示与否的方法
- TCGA数据库中癌症名称缩写
- CloudFlare自定义节点优化网站
- 什么是SSL?为什么要为WordPress网站使用SSL?
- R语言再保险合同定价案例研究
- SAP CRM附件的技术属性设计原理
- R语言对混合分布中的不可观测与可观测异质性因子分析
- R替换函数gsub
- R语言泊松回归对保险定价建模中的应用:风险敞口作为可能的解释变量
- asp dotnet core 提供大文件下载的测试
- R语言模拟人类生活预期寿命动态可视化动画图gif