dubbo @Activate 注解使用和实现解析
Activate注解表示一个扩展是否被激活(使用),可以放在类定义和方法上,
dubbo用它在spi扩展类定义上,表示这个扩展实现激活条件和时机。
先看下定义:
@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,返回要激活使用的扩展。
/**
* Dubbo使用的扩展点获取。<p>
* <ul>
* <li>自动注入关联扩展点。</li>
* <li>自动Wrap上扩展点的Wrap类。</li>
* <li>缺省获得的的扩展点是一个Adaptive Instance。
* </ul>
*/
public class ExtensionLoader<T> 类中有如下四个方法 /**
* 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 @Activate 注解使用和实现解析的更多相关文章
- dubbo系列七、dubbo @Activate 注解使用和实现解析
一.用法 Activate注解表示一个扩展是否被激活(使用),可以放在类定义和方法上,dubbo用它在spi扩展类定义上,表示这个扩展实现激活条件和时机. @Activate(group = Cons ...
- Spring Boot 中如何使用 Dubbo Activate 扩展点
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 公司的核心竞争力在于创新 – <启示录> 』 继续上一篇:< Spri ...
- Activate注解
Activate注解 被该注解修饰的接口,扩展类可能会被加载 ProtocolFilterWrapper.buildInvokerChain @Documented @Retention(Retent ...
- dubbo注册中心占位符无法解析问题
dubbo注册中心占位符无法解析问题 1.背景 最近搞了2个老项目,想把他们融合到一起.这俩项目情况简介如下: 项目一:基于SpringMVC + dubbo,配置读取本地properties文件,少 ...
- 第5章—构建Spring Web应用程序—关于spring中的validate注解后台校验的解析
关于spring中的validate注解后台校验的解析 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判 ...
- Dubbo通过注解实现RPC调用
启动Dubbo服务有2个方式,1是通过xml配置,2是通过注解来实现,这点和Spring相似. 采用XML配置如下: <?xml version="1.0" encodin ...
- dubbo注册中心占位符无法解析问题(二)
dubbo注册中心占位符无法解析问题 前面分析了dubbo注册中心占位符无法解析的问题. 并给出了2种解决办法: 降低mybatis-spring的版本至2.0.1及以下 自定义MapperScann ...
- 第四章 dubbo内核之aop源码解析
ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class); final P ...
- Spring提取@Transactional事务注解的源码解析
声明:本文是自己在学习spring注解事务处理源代码时所留下的笔记: 难免有错误,敬请读者谅解!!! 1.事务注解标签 <tx:annotation-driven /> 2.tx 命名空间 ...
随机推荐
- 细说java系列之注解
写在前面 Java从1.5版本之后开始支持注解,通过注解可以很方便地实现某些功能,使用得最普遍的就是Spring框架的注解,大大简化了Bean的配置. 注解仅仅是一种Java提供的工具,并不是一种编程 ...
- redis集群之主从架构
https://redis.io/topics/replication1. redis主从架构概述(1)一个master可以配置多个slave(2)slave与master之间使用异步复制进行数据同步 ...
- Ext.net 的锁定列要集中放到前面
如题,Ext.net的锁定列要集中放在一起,不然的话,在使用排序的时候,会引起实际排序列错乱比如有A,B,C,D四列,A,C锁定,最终显示为A C | B D,这个时候如果点击B时,发现排序跑到了C上 ...
- 利用PHP实现登录与注册功能以及使用PHP读取mysql数据库——以表格形式显示数据
登录界面 <body><form action="login1.php" method="post"><div>用户名:&l ...
- PHP获取表单并使用数组存储 疯狂提示 Notice: Undefined offset
$answer=array(); $answer[0]='0'; for($i=1;$i<=$QUESTION_COUNT;$i++){ $answer[$i]=$_POST[(string)$ ...
- 第21月第9日 windows下使用vim+ctags+taglist
1. windows下使用vim+ctags+taglist 最近在公司的同事指导下,学会使用这个东西编写代码,效率提高了不少.所以记录下来,方便大家使用. 1. 下载gvim74.exe文件,并安装 ...
- 单片机AT和STC区别
http://www.21ic.com/jichuzhishi/datasheet/AT89C51/data/192017.html
- linux find 只获取文件名而去除路径
find /var/process_log/ -name '*.log' -exec basename {} \;
- Failed to read artifact descriptor for org.apache.maven.plugins:maven-install-plugin-JavaWeb(四)
今天使用maven clean, maven install 出现了下图问题,只解决了 maven clean , 还有maven install 今天 使用maven clean 出现以下问题(把下 ...
- 搜索jar包 出现很多 Artifact Id相同 但Group Id不同 的包
举例:将传统本地 javassit-3.17.1-GA.jar包 改成maven引用,pom中 ---Add 输入javassit 搜索 这时候会搜索出超级多 Artifact Id相同 但Group ...