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 注解使用和实现解析的更多相关文章

  1. dubbo系列七、dubbo @Activate 注解使用和实现解析

    一.用法 Activate注解表示一个扩展是否被激活(使用),可以放在类定义和方法上,dubbo用它在spi扩展类定义上,表示这个扩展实现激活条件和时机. @Activate(group = Cons ...

  2. Spring Boot 中如何使用 Dubbo Activate 扩展点

    摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 公司的核心竞争力在于创新 – <启示录> 』 继续上一篇:< Spri ...

  3. Activate注解

    Activate注解 被该注解修饰的接口,扩展类可能会被加载 ProtocolFilterWrapper.buildInvokerChain @Documented @Retention(Retent ...

  4. dubbo注册中心占位符无法解析问题

    dubbo注册中心占位符无法解析问题 1.背景 最近搞了2个老项目,想把他们融合到一起.这俩项目情况简介如下: 项目一:基于SpringMVC + dubbo,配置读取本地properties文件,少 ...

  5. 第5章—构建Spring Web应用程序—关于spring中的validate注解后台校验的解析

    关于spring中的validate注解后台校验的解析 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判 ...

  6. Dubbo通过注解实现RPC调用

    启动Dubbo服务有2个方式,1是通过xml配置,2是通过注解来实现,这点和Spring相似. 采用XML配置如下:  <?xml version="1.0" encodin ...

  7. dubbo注册中心占位符无法解析问题(二)

    dubbo注册中心占位符无法解析问题 前面分析了dubbo注册中心占位符无法解析的问题. 并给出了2种解决办法: 降低mybatis-spring的版本至2.0.1及以下 自定义MapperScann ...

  8. 第四章 dubbo内核之aop源码解析

    ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class); final P ...

  9. Spring提取@Transactional事务注解的源码解析

    声明:本文是自己在学习spring注解事务处理源代码时所留下的笔记: 难免有错误,敬请读者谅解!!! 1.事务注解标签 <tx:annotation-driven /> 2.tx 命名空间 ...

随机推荐

  1. 【转载】RPG颜色参考表

    https://blog.csdn.net/a949308398/article/details/17013087

  2. Java爬网页数据,并存储到本地数据库中

    由于开发一个人工智能项目,需要强大的后台数据库加持,所以,没有办法,又是需要医疗数据,只能自己爬某医疗网站数据,进行分析,但是由于不同网站的结构不一样,所以这个程序只能爬该网站的,第一次爬网页数据,自 ...

  3. 开发mis系统需要的技术

    一.b/s架构 b/s架构:就broser/server,浏览器/服务器的说法.服务器端要运行tomcat,提供链接数据库服务供java代码读写数据,这个可以在eclipse中配置运行.浏览器则解释j ...

  4. 007_Reverse Integer

    ###solution1####small data # def reverse(x): # res=[] # t=0 # p=1 #记录位数 # y=x # if x<0: # x=-x # ...

  5. oracle存储过程---创建存储过程语句

    一.创建存储过程语句 语法:  CREATE OR REPLACE PROCEDURE testname( argument1 TYPE1, ....  ) AS BEGIN ...... END  ...

  6. C - CodeCoder vs TopForces Gym - 101142C (连通块+思维)

    题目链接: C - CodeCoder vs TopForces Gym - 101142C 题目大意:给你n个人的信息,每一个人的信息包括两个.t1和t2.A>B的前提是A的t1和t2至少有一 ...

  7. mysql案例~关于linux服务器本身的优化问题

    简介:mysql服务优化分为 1服务器本身的优化 2mysql本身的性能优化 今天咱们来讨论下服务器本身的优化性能 一 参数的优化简介 1 文件系统的选择 Linux 常用文件系统: ext3, ex ...

  8. python - 编程规范问题

    软件目录结构规范alex_老男孩:为什么要设计好目录结构?“设计项目目录结构”,就和“胆码编码风格”一样,属于个人风格问题.对于这种风格上的规范,一直都存在两种态度:    1.一类同学认为,这种个人 ...

  9. Required String parameter 'images' is not present

    后台控制层控制为非必填即可: @RequestMapping("/addDo") @SJson @SLog(description = "Car_main") ...

  10. 安卓虚拟机与Hyper-V冲突

    经过各种经验,哪个安卓虚拟机跟Hyper-V都存在着冲突. 解决方案一 程序中卸载Hyper-V,之后还要再配置太麻烦. 解决方案二 1.关掉Hyper-V的启动项,命令如下. bcdedit /se ...