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;
}
dubbo系列七、dubbo @Activate 注解使用和实现解析的更多相关文章
- dubbo @Activate 注解使用和实现解析
Activate注解表示一个扩展是否被激活(使用),可以放在类定义和方法上, dubbo用它在spi扩展类定义上,表示这个扩展实现激活条件和时机. 先看下定义: @Documented @Retent ...
- Spring框架系列(七)--Spring常用注解
Spring部分: 1.声明bean的注解: @Component:组件,没有明确的角色 @Service:在业务逻辑层使用(service层) @Repository:在数据访问层使用(dao层) ...
- Spring系列之手写注解与配置文件的解析
目录 Spring系列之IOC的原理及手动实现 Spring系列之DI的原理及手动实现 Spring系列之AOP的原理及手动实现 引入 在前面我们已经完成了IOC,DI,AOP的实现,基本的功能都已经 ...
- java基础解析系列(七)---ThreadLocal原理分析
java基础解析系列(七)---ThreadLocal原理分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)-- ...
- Dubbo系列之 (七)链路层那些事(1)
辅助链接 Dubbo系列之 (一)SPI扩展 Dubbo系列之 (二)Registry注册中心-注册(1) Dubbo系列之 (三)Registry注册中心-注册(2) Dubbo系列之 (四)服务订 ...
- Dubbo系列之 (七)网络层那些事(2)
辅助链接 Dubbo系列之 (一)SPI扩展 Dubbo系列之 (二)Registry注册中心-注册(1) Dubbo系列之 (三)Registry注册中心-注册(2) Dubbo系列之 (四)服务订 ...
- Dubbo 系列(07-5)集群容错 - Mock
Dubbo 系列(07-5)集群容错 - Mock [toc] Spring Cloud Alibaba 系列目录 - Dubbo 篇 1. 背景介绍 相关文档推荐: Dubbo 实战 - 服务降级 ...
- Spring Cloud 系列之 Dubbo RPC 通信
Dubbo 介绍 官网:http://dubbo.apache.org/zh-cn/ Github:https://github.com/apache/dubbo 2018 年 2 月 15 日,阿里 ...
- Dubbo系列之 (一)SPI扩展
一.基础铺垫 1.@SPI .@Activate. @Adaptive a.对于 @SPI,Dubbo默认的特性扩展接口,都必须打上这个@SPI,标识这是个Dubbo扩展点.如果自己需要新增dubbo ...
随机推荐
- Python--Django学习笔记2
本篇介绍Django中的Model层. 首先介绍sqlite3,这是在当前版本中Django默认使用的数据库,sqlite也是Android中所使用的数据库. 接着介绍最最最常见的MySQL数据库如何 ...
- TextView 借助Linkify,使用自定义模式设置链接
http://my.oschina.net/fengheju/blog/176105 TextView是android中的一个比较常用的控件,它有一个非常有趣的特性,可以通过android:autoL ...
- 使用fiddler模拟http请求
概述 与httpwath相比,fiddler能模拟http请求.能断点调试.http分析统计吸引了我,使用之后感觉这个工具非常不错,这篇文章只单介绍一下fiddler工作原理,简单介绍一下它的重要功 ...
- Luogu 2679 子串 (动态规划)
Luogu 2679 NOIP 2015 子串 (动态规划) Description 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k ...
- javascript:window.location.replace 与 window.location.reload() 刷新页面的不同效果
今天早上我发现一个问题,当一个网页的地址最后面是一个#时(比如:http://www.baidu.com/go.asp#), 执行:window.location.replace(window.loc ...
- ReactNative组件之scrollView实现轮播
想要实现轮播效果,首先安装时间定时器 接下来就是在我们的项目中使用定时器 接下来我们将竖着的轮播图变成横着的 接下来我们调整间距 我们知道轮播图下方,还有5个圆点,那我们怎么做呢? 拿到每一个圆点 看 ...
- TCP协议、UDP协议、端口、套接字
TCP协议优缺点 可靠:反馈数据是否送达 效率低:需要创建连接请求,连接成功后发数据 UDP协议优缺点 不可靠:无任何反馈 效率高:不创建连接请求,直接发数据 端口(0~65535,其中0~1023用 ...
- 数据分析工具urule
Python统计学书籍 https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-13911786811.22.6431353b4F5iw1& ...
- 设计模式---单一职责模式之装饰模式(Decorator)
前提:"单一职责"模式 在软件组件的设计中,如果责任划分的不清晰,使用继承,得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任 典型模式(表现 ...
- linq总结系列(二)---Expression
一.linq中的表达式和表达式树 Linq中的表达式(Expression<TDel>)是强类型的lambda表达式,对Func和Action形式的委托做了一层封装. lambda表达式的 ...