Activate注解
Activate注解
被该注解修饰的接口,扩展类可能会被加载
ProtocolFilterWrapper.buildInvokerChain
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Activate {
/**
* 激活当前扩展类的条件之一, 该group参数将会与ExtensionLoader#getActivateExtension方法传入的gruop参数进行匹配
* @return 要匹配的组名
* @see ExtensionLoader#getActivateExtension(URL, String, String)
*/
String[] group() default {};
/**
当URL中出现该value值时激活扩展类
例如:@Activate("cache, validation")注释在一个接口上,当URL中有cache或者validation参数时激活
* @return URL对应的参数的keys
* @see ExtensionLoader#getActivateExtension(URL, String)
* @see ExtensionLoader#getActivateExtension(URL, String, String)
*/
String[] value() default {};
/**
* 排序信息,可选
* @return 在当前扩展类执行之前的扩展类
*/
String[] before() default {};
/**
* 排序信息,可选
* @return 在当前扩展类执行之后的扩展类
*/
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指定)传递了group = Constants.PROVIDER 或者Constants.CONSUMER则该Filter激活
//再看这个扩展 这个类是在下下面第四个方法的第一部分解析的
@Activate(group = Constants.PROVIDER, value = Constants.TOKEN_KEY)
public class TokenFilter implements Filter {
}
如果过滤器使用方(通过group指定)指定group=Constants.PROVIDER并且URL中有参数Constants.TOKEN_KEY,那么激活这个Filter
dubbo中在加载配置文件时会将@Activate修饰的类(实现类)添加到cachedActivates中,在这儿ExtensionLoader#loadClass
/** key: 扩展名, value: 具体扩展对象 */
private final Map<String, Activate> cachedActivates = new ConcurrentHashMap<String, Activate>();
Activate activate = clazz.getAnnotation(Activate.class);
if (activate != null) {
// param1: 扩展名 param2: 具体的实现类
cachedActivates.put(names[0], activate);
}
然后ExtensionLoader提供了4个方法来具体使用cachedActivates,返回要激活使用的扩展类。
/**
* 相当于调用 getActivateExtension(url, key, null);
* 从URL中获取扩展点的名字,然后在所有的激活中(@Activate修饰的类),获取扩展对象
* @param url url
* @param key 用于从URL中获取扩展点的名字(即:扩展点名字的key)
* @return 激活的扩展集合
* @see #getActivateExtension(com.alibaba.dubbo.common.URL, String, String)
*/
public List<T> getActivateExtension(URL url, String key)
/**
* 相当于调用 getActivateExtension(url, values, null);
* 在所有的激活中 values指定的扩展
* @param url url
* @param values 扩展点名字数组
* @return extension list which are activated
* @see #getActivateExtension(com.alibaba.dubbo.common.URL, String[], String)
*/
public List<T> getActivateExtension(URL url, String[] values)
/**
*
* 相当于调用 getActivateExtension(url, url.getParameter(key).split(","), null); 不是有group?为什么相当于这个方法??
* </pre>
* 在所有的激活中,@Activate的group参数等于这个参数group
* @param url url
* @param key 扩展点的名字
* @param group 指定的gruop
* @return 激活的扩展集合
* @see #getActivateExtension(com.alibaba.dubbo.common.URL, String[], String)
*/
public List<T> getActivateExtension(URL url, String key, String group)
/**
* 获取激活扩展
* @param url url
* @param values 扩展点的名字数组
* @param group group
* @return 满足条件的扩展集合
* @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);
// URL中没有server.filter=-default(这代表去掉所有默认过滤器)
if (!names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {
getExtensionClasses();
//cachedActivates里放的map结构 接口实现扩展名:其上的Activate对象
//遍历所有Activate注解对象
for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {
//spi 扩展类在配置文件中的key
String name = entry.getKey();
Activate activate = entry.getValue();
//如果有group匹配
if (isMatchGroup(group, activate.group())) {
//获取扩展类
T ext = getExtension(name);
//1、name不在 values 指定之列
//2、并且没排除name,
//3、如果扩展类的Activate有value值,并且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);
}
//下面这部分是直接获取values扩展名中对应的扩展类
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)) {
//如果name为default,则将默认的过滤器添加到集合的开始
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;
}
关于最后一个获取扩展的方法,可以这样理解:
names(=values) 是URL中指定的激活(去掉激活)的值, service.filter=-default 就去掉了所有默认的filter(包括自定义让dubbo扫描的)
registry://192.168.1.7:9090/com.alibaba.service1?server.filter=-defalut,value1 去掉默认的,添加value1
registry://192.168.1.7:9090/com.alibaba.service1?server.filter=value1,-value2 去掉value2,添加value1
关于激活的过滤器我们总结一下:
都需要在扩展类的配置文件中标识 过滤器名=xxx.xxx.xxx.xxxFilter
默认过滤器
需要被@Activate标识
如果需要在服务暴露时装载,那么group="provider"
如果需要在服务引用的时候装载,那么group="consumer"
如果想被暴露和引用时同时被装载,那么group={"consumer", "provider"}
如果需要url中有某个特定的值才被加载,那么value={"token", "bb"}
那么就需要配置一个token, value数组与URL中的某一个属性相同就行了
普通自定义过滤器
需要配置在url上 比如 <dubbo:provider filter="myFilter" />
过滤器扩展类上可以有@Activate也可以没有(自定义的就不要加了)
去掉某个过滤器
在filter属性上使用-号标识需要去掉的过滤器 比如:<dubbo:provider filter="-monitor" />
Activate注解的更多相关文章
- dubbo @Activate 注解使用和实现解析
Activate注解表示一个扩展是否被激活(使用),可以放在类定义和方法上, dubbo用它在spi扩展类定义上,表示这个扩展实现激活条件和时机. 先看下定义: @Documented @Retent ...
- dubbo系列七、dubbo @Activate 注解使用和实现解析
一.用法 Activate注解表示一个扩展是否被激活(使用),可以放在类定义和方法上,dubbo用它在spi扩展类定义上,表示这个扩展实现激活条件和时机. @Activate(group = Cons ...
- Spring Boot 中如何使用 Dubbo Activate 扩展点
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 公司的核心竞争力在于创新 – <启示录> 』 继续上一篇:< Spri ...
- Dubbo扩展点应用之一filter及@Activate自激活使用
与很多框架一样,Dubbo也存在拦截(过滤)机制,可以通过该机制在执行目标程序前后执行我们指定的代码.Dubbo中Filter只是Dubbo提供的可自定义扩展的扩展点之一.通过该扩展点地理解,可以触类 ...
- Spring Dubbo 开发笔记(一)——概述
概述: Spring Dubbo 是我自己写的一个基于spring-boot和dubbo,目的是使用Spring boot的风格来使用dubbo.(即可以了解Spring boot的启动过程又可以学习 ...
- Spring Dubbo 开发笔记
第一节:概述 Spring-Dubbo 是我自己写的一个基于spring-boot和dubbo,目的是使用Spring boot的风格来使用dubbo.(即可以了解Spring boot的启动过程又可 ...
- spring-boot整合dubbo:Spring-boot-dubbo-starter
为什么要写这个小工具 如果你用过Spring-boot来提供dubbo服务,相信使用中有很多"不爽"的地方.既然使用spring boot,那么能用注解的地方绝不用xml配置,这才 ...
- dubbo源码—SPI
Java中的SPI SPI,Service Provider Interface,java中提供的一种使程序可扩展的方式,系统定义好接口规范,供其他服务提供方实现,服务提供方将自己jar包META-I ...
- Dubbo中SPI扩展机制解析
dubbo的SPI机制类似与Java的SPI,Java的SPI会一次性的实例化所有扩展点的实现,有点显得浪费资源. dubbo的扩展机制可以方便的获取某一个想要的扩展实现,每个实现都有自己的name, ...
随机推荐
- spring cloud 常见面试题 来理解微服
为什么要谈 这些理论知识呢 理论知识 = 面试时候的谈资 !!! 你只有 进去公司 才有资格 去做一个码农 ok 话不多说 经历如此漫长的互联网发展 以本人的拙见 软件开发 粗略的 分为 ...
- Python性能监控
profiler是一个程序,用来描述运行时的程序性能,并且从不同方面提供统计数据加以表述.Python中含有3个模块提供这样的功能,分别是cProfile, profile和pstats.这些分析器提 ...
- GC和GC分配策略
一.内存如何回收 解决如何回收问题,首先需要解决回收对象的问题?什么样的对象需要回收,怎么样的不需要回收?保证有引用的内存不被释放:回收没有指针引用的内存是Collector的职责,在保证没有指针引用 ...
- [Linux] pwm设备驱动调试
转载请注明出处:https://www.cnblogs.com/lialong1st/p/11436190.html CPU:RK3288 系统:Linux 客户需求是通过 pwm 控制激光的强弱,写 ...
- pytorch基础学习(二)
在神经网络训练时,还涉及到一些tricks,如网络权重的初始化方法,优化器种类(权重更新),图片预处理等,继续填坑. 1. 神经网络初始化(Network Initialization ) 1.1 初 ...
- ISO/IEC 9899:2011 条款6.2.2——标识符的连接
6.2.2 标识符的连接 1.在不同作用域中声明的一个标识符或在同一作用域多次出现的一个标识符可以被用作对同一个对象或函数的引用,通过一个称为连接的过程.[注:在两个不同的标识符之间没有连接.]有三种 ...
- 快速查看MySQL数据库的版本号
1.利用dos命令连接数据库后即有版本号信息 2.利用navicat连接mysql的客户端工具也是可以查看的 直接选中一个连接,然后右键-连接信息查看 3.利用专门的mysql命令查看 4.直接查看咱 ...
- lua table操作
求最大值,最小值及长度: function maxn(t) local mn = nil for i, v in pairs(t) do if (mn==nil) then mn=v end if ( ...
- ALV显示金额字段值扩大100倍
内表数据 物料 库位 期末庫存金額F0D7004DSA 1PYF 701410.944F0D7004DSA 1SNT ...
- git命令手册
以下内容是我在学习和研究Git时,对Git操作的特性.重点和注意事项的提取.精练和总结,可以做为Git操作的字典,方便大家查阅: 备注:本文会不断更新完善: 目录 一. 语法格式描述 二. git环境 ...