https://blog.csdn.net/prestigeding/article/details/82085705

 从上文可知,在服务的调用或消费端发送请求命令中,Dubbo引入过滤器链机制来实现功能的包装(或扩展)。Dubbo很多功能,例如泛化调用、并发控制等都是基于Filter机制实现的,系统默认的Filter在/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Filter文件中定义,内容如下:

echo=com.alibaba.dubbo.rpc.filter.EchoFilter
generic=com.alibaba.dubbo.rpc.filter.GenericFilter
genericimpl=com.alibaba.dubbo.rpc.filter.GenericImplFilter
token=com.alibaba.dubbo.rpc.filter.TokenFilter
accesslog=com.alibaba.dubbo.rpc.filter.AccessLogFilter
activelimit=com.alibaba.dubbo.rpc.filter.ActiveLimitFilter
classloader=com.alibaba.dubbo.rpc.filter.ClassLoaderFilter
context=com.alibaba.dubbo.rpc.filter.ContextFilter
consumercontext=com.alibaba.dubbo.rpc.filter.ConsumerContextFilter
exception=com.alibaba.dubbo.rpc.filter.ExceptionFilter
executelimit=com.alibaba.dubbo.rpc.filter.ExecuteLimitFilter
deprecated=com.alibaba.dubbo.rpc.filter.DeprecatedFilter
compatible=com.alibaba.dubbo.rpc.filter.CompatibleFilter
timeout=com.alibaba.dubbo.rpc.filter.TimeoutFilter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
   以其中一个来说明一下Filter的定义要素:

/**
* EchoInvokerFilter
*/
@Activate(group = Constants.PROVIDER, order = -110000) // @2
public class EchoFilter implements Filter { // @1

@Override
public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
if (inv.getMethodName().equals(Constants.$ECHO) && inv.getArguments() != null && inv.getArguments().length == 1)
return new RpcResult(inv.getArguments()[0]);
return invoker.invoke(inv);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
   代码@1:实现com.alibaba.dubbo.rpc.Filter接口。
   代码@2:添加Activate,其注解含义如下:
   group: 所属组,String[],例如消费端、服务端。
   value String[],如果指定该值,只有当消费者或服务提供者URL中包含属性名为value的键值对,该过滤器才处于激活状态。
   before:String[],用于指定执行顺序,before指定的过滤器在该过滤器之前执行。
   after:string[],用于指定执行顺序,after指定的过滤器在该过滤器之后执行。
   order:用户指定顺序,值越小,越先执行。
   除了支持默认的过滤器外,Dubbo还支持自定义Filter,可以通过service.filter指定过滤器,多个用英文逗号隔开,其配置方法为:
   < dubbo:service ……>
      < dubbo:parameter key = “service.filter” value = “filter1,filer2,…”/>
   < /dubbo:service>
   当然,可以为所有服务提供者设置共用过滤器,其指定方法为:
   < dubbo:provider …>
      < dubbo:parameter key = “service.filter” value = “filter1,filer2,…”/>
   < /dubbo:provider>
   消费端自定义过滤器的key为reference.filter,其使用方法在< dubbo:reference/>标签或< dubbo:consumer/>标签下定义属性。
   关于自定义Filter的解析代码如下:
   ExtensionLoader#getActivateExtension

public List<T> getActivateExtension(URL url, String key, String group) { // @1
String value = url.getParameter(key); // @2
return getActivateExtension(url, value == null || value.length() == 0 ? null : Constants.COMMA_SPLIT_PATTERN.split(value), group); // @3
}
1
2
3
4
   代码@1:参数说明。
   URL url:服务提供者或服务消费者url。
   String key:过滤器属性key,服务提供者固定为:service.filter,服务消费者固定为reference.filter。
   String group:服务提供者或服务消费者。
   代码@2:从url中获取配置的自定义filter。
   代码@3:如果value不为空,则将字符串调用split转换为数组,然后调用getActivateExtension方法,获取符合条件的过滤器。
   ExtensionLoader#getActivateExtension

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)) { // @1
getExtensionClasses(); // @2
for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {
String name = entry.getKey();
Activate activate = entry.getValue();
if (isMatchGroup(group, activate.group())) { // @3
T ext = getExtension(name);
if (!names.contains(name)
&& !names.contains(Constants.REMOVE_VALUE_PREFIX + name) // @4
&& isActive(activate, url)) { // @5
exts.add(ext);
}
}
}
Collections.sort(exts, ActivateComparator.COMPARATOR);
}
List<T> usrs = new ArrayList<T>();
for (int i = 0; i < names.size(); i++) { // @6
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.isEmpty()) {
exts.addAll(0, usrs);
usrs.clear();
}
} else {
T ext = getExtension(name);
usrs.add(ext);
}
}
}
if (!usrs.isEmpty()) {
exts.addAll(usrs);
}
return exts;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
   代码@1:如果配置的service.filter或referecnce.filter包含了-default,表示禁用系统默认提供的一系列过滤器。
   代码@2:如果不禁用系统默认过滤器链,则首先加载所有默认过滤器。
   代码@3:根据group刷选出适配的过滤器。
   代码@4:也可以对单个filter进行禁用,其方法是-过滤器名称的方式。例如如想禁用AccessLogFilter,则可以通过-accesslog方式禁用。-key,key为/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.r
pc.Filter中定义的key。
   代码@5:判断过滤器是否激活,其逻辑是如果Filter上的@Activate注解value值不为空,则需要判断url中是否包含键为value的属性对,存在则启用,不存在则不启用。
   代码@6:加载用户自定义的Filter,也即是service.filter或reference.filter指定的过滤器。
   综上所述,Dubbo提供了过滤器机制,在真实服务被调用前提供扩展点。Filter机制就简单介绍到这里了,从下文开始会重点分析Dubbo服务提供的核心Filter。
   如果需要自定过滤器,需要在自定的工程中META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Filter文件中注册。
   本文就介绍到这里了,从下篇开始将会根据Dubbo的功能特性来详细分析其实现过程,其本质都是各种Dubbo 过滤器器。
————————————————
版权声明:本文为CSDN博主「唯有坚持不懈」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/prestigeding/article/details/82085705

Dubbo Filter机制概述的更多相关文章

  1. 基于SLF4J的MDC机制和Dubbo的Filter机制,实现分布式系统的日志全链路追踪

    原文链接:基于SLF4J的MDC机制和Dubbo的Filter机制,实现分布式系统的日志全链路追踪 一.日志系统 1.日志框架 在每个系统应用中,我们都会使用日志系统,主要是为了记录必要的信息和方便排 ...

  2. Android广播机制概述

    1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通 ...

  3. Dubbo SPI 机制源码分析(基于2.7.7)

    Dubbo SPI 机制涉及到 @SPI.@Adaptive.@Activate 三个注解,ExtensionLoader 作为 Dubbo SPI 机制的核心负责加载和管理扩展点及其实现.本文以 E ...

  4. SQL Server 内存中OLTP内部机制概述(四)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  5. SQL Server 内存中OLTP内部机制概述(三)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  6. SQL Server 内存中OLTP内部机制概述(二)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  7. SQL Server 内存中OLTP内部机制概述(一)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  8. VS2010/MFC编程入门之五(MFC消息映射机制概述)

    VS2010/MFC编程入门之五(MFC消息映射机制概述)-软件开发-鸡啄米 http://www.jizhuomi.com/software/147.html 上一讲鸡啄米为大家简单分析了MFC应用 ...

  9. JVM垃圾回收机制概述

    JVM垃圾回收机制概述 1.定义 是指JVM用于释放那些不再使用的对象所占用的内存. 2.方式 2.1引用计数(早期) 当引用程序创建引用以及引用超出范围时,JVM必须适当增减引用数.当某个对象的引用 ...

随机推荐

  1. android ListView中含有按钮事件实时更新ListView数据案例

    1.布局文件Listview <?xml version="1.0" encoding="utf-8"?> <android.support. ...

  2. 关于mysql数据库涉及的一些规范

    tips:如果本文对你有用,请爱心点个赞,提高排名,让这篇文章帮助更多的人.谢谢大家!比心❤~ 如果解决不了,可以在文末加我微信,进群交流. 设计规范,在分工协作的工作场景中尤其重要,否则团队之间互相 ...

  3. ExtendEvent-判断DB是否有在使用

    判断一个DB是否在被使用,需要观察一段时间,创建一个扩展事件会话,收集该DB是否有执行SQL即可. 创建会话 CREATE EVENT SESSION [DB_Usage] ON SERVER ) A ...

  4. SAMBA配置文件详解

    全局参数: ==================Global Settings =================== [global] config file = /usr/local/samba/ ...

  5. Httpd服务入门知识-Httpd服务安装

    Httpd服务入门知识-Httpd服务安装 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Httpd概述 1>.Httpd介绍 20世纪90年代初,国家超级计算机应用中心 ...

  6. 随笔记录--Array类型

    前言:除了Object类型之外,Array类型恐怕是ECMAScript中最常用的类型了.而且,ECMAScript中数组与其他多数语言中的数组有很大差别,ECMAScript数组中的每一项可以保存任 ...

  7. DFS 算法模板

    dfs算法模板: 1.下一层是多节点的dfs遍历 def dfs(array or root, cur_layer, path, result): if cur_layer == len(array) ...

  8. HDU5036(bitset加速传递闭包+期望)

    HDU5036 题解 题目链接 思路: 求出破坏or打开所有门所需要的期望炮弹数量,那么根据期望的线性性质,我们可以求出每一个门的期望值最后累加起来就行了. 我们最后的目标就是求对于一个门\(i\), ...

  9. HDU4624 Endless Spin 和 HAOI2015 按位或

    Endless Spin 给你一段长度为[1..n]的白色区间,每次随机的取一个子区间将这个区间涂黑,问整个区间被涂黑时需要的期望次数. n<=50 题解 显然是min-max容斥,但是n的范围 ...

  10. 常用 shell 命令 chmod | root

    chmod 命令 chmod 命令 [格式1:] chmod [ugoa][+-=][rwx] 文件或目录 /*u.g.o.a : u属主,g属组,o其他用户,a所有用户*/ /*+.-.= : 增加 ...