Dubbo的Filter执行顺序分析
2018-01-23 00:00
363 查看
摘要: Dubbo Filter 顺序
最近用到了Dubbo的Filter来做一些监控的东西,顺便整理了一下dubbo中的Filter调用顺序及如何确定的。
服务提供方的过滤器被调用顺序:
EchoFilter->ClassLoaderFilter->GenericFilter->ContextFilter->(这4个是在代码中指定的)
ExceptionFilter-> TimeoutFilter ->MonitorFilter-> TraceFilter
服务消费方的过滤器顺序:
ConsumerContextFilter->FutureFilter->MonitorFilter
负责加载过滤器的类
ProtocolFilterWrapper
这个顺序和SPI配置文件的顺序并不一致。那么是什么决定了Filter的顺序呢?
通过查看源代码可以看到,在初始化Filter时,有一个对所有的过滤器排序的过程,其使用的比较类是ActivateComparator。在这个类中,可以看到,是使用Filter中的Activate类进行排序的。而Activate注解中,有一个order的属性,这个属性指定了Filter在chain中的顺序。代码如下:
通过查看EchoFilter的Activate属性,可以看到其order = -110000,而ClassLoaderFilter的order=-30000,因此可以断定,order值越小,其越位于调用端的最顶层。
如下:
从上面可以看出,如果需要规定自定义的Filter的执行顺序,可以通过设置自定义的Filter的@Active注解中order属性值,越小越先执行。
那么当order相同时(都没有设置时),又是根据什么排序的呢?
Collections.sort算法
从其说明文档可以看出,这个算法是一个稳定的排序算法,如果两个值相同,不会改变其前后顺序。并且从其文档可以看出,其所使用的是一个修改过的归并排序算法。
但是Activate的compare方法故意将两个相同的order类弄成了不同,导致排序有些变化。造成了最终上述顺序。
所以导致原来配置文件中的位置为:
1、monitor
2、trace
3、exception
4、timeout
排序后变成了
1、exception
2、timeout
3、monitor
4、trace
参考文献:http://blog.csdn.net/skiof007/article/details/51953497
最近用到了Dubbo的Filter来做一些监控的东西,顺便整理了一下dubbo中的Filter调用顺序及如何确定的。
服务提供方的过滤器被调用顺序:
EchoFilter->ClassLoaderFilter->GenericFilter->ContextFilter->(这4个是在代码中指定的)
ExceptionFilter-> TimeoutFilter ->MonitorFilter-> TraceFilter
服务消费方的过滤器顺序:
ConsumerContextFilter->FutureFilter->MonitorFilter
负责加载过滤器的类
ProtocolFilterWrapper
这个顺序和SPI配置文件的顺序并不一致。那么是什么决定了Filter的顺序呢?
通过查看源代码可以看到,在初始化Filter时,有一个对所有的过滤器排序的过程,其使用的比较类是ActivateComparator。在这个类中,可以看到,是使用Filter中的Activate类进行排序的。而Activate注解中,有一个order的属性,这个属性指定了Filter在chain中的顺序。代码如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface Activate { String[] group() default {}; String[] value() default {}; String[] before() default {}; String[] after() default {}; int order() default 0; }
通过查看EchoFilter的Activate属性,可以看到其order = -110000,而ClassLoaderFilter的order=-30000,因此可以断定,order值越小,其越位于调用端的最顶层。
如下:
@Activate( group = {"provider"}, order = -110000 ) public class EchoFilter implements Filter { public EchoFilter() { } public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException { return (Result)(inv.getMethodName().equals("$echo") && inv.getArguments() != null && inv.getArguments().length == 1 ? new RpcResult(inv.getArguments()[0]) : invoker.invoke(inv)); } }
@Activate( group = {"provider"}, order = -30000 ) public class ClassLoaderFilter implements Filter { public ClassLoaderFilter() { } public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { ClassLoader ocl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(invoker.getInterface().getClassLoader()); Result var4; try { var4 = invoker.invoke(invocation); } finally { Thread.currentThread().setContextClassLoader(ocl); } return var4; } }
从上面可以看出,如果需要规定自定义的Filter的执行顺序,可以通过设置自定义的Filter的@Active注解中order属性值,越小越先执行。
那么当order相同时(都没有设置时),又是根据什么排序的呢?
Collections.sort算法
从其说明文档可以看出,这个算法是一个稳定的排序算法,如果两个值相同,不会改变其前后顺序。并且从其文档可以看出,其所使用的是一个修改过的归并排序算法。
但是Activate的compare方法故意将两个相同的order类弄成了不同,导致排序有些变化。造成了最终上述顺序。
所以导致原来配置文件中的位置为:
1、monitor
2、trace
3、exception
4、timeout
排序后变成了
1、exception
2、timeout
3、monitor
4、trace
参考文献:http://blog.csdn.net/skiof007/article/details/51953497
相关文章推荐
- Servlet、Filter 和 Listener 调用顺序、生命周期的实验分析
- 关于Java中try finally return语句的执行顺序分析
- Servlet中filter的执行顺序以及urlPatterns和servletNames之间的关系
- java中return与finally的执行顺序分析(根据字节码分析)
- Asp.net Mvc (Filter及其执行顺序)
- 多个$(document).ready()的执行顺序实例分析
- filter执行顺序与实例
- FILTER的执行顺序
- 验证多个Filter过滤一个资源时执行顺序
- 网站性能分析(下)-让网站并行加载但顺序执行JS
- Junit执行及加载顺序分析(原创)
- mysql 执行顺序 SQL语句执行顺序分析
- SQL语句执行顺序分析
- [转]servlet 和filter区别和servlet、filter、interceptor的执行顺序
- 浅谈SQL语句执行顺序分析
- JavaScript同步、异步、回调执行顺序之经典闭包(setTimeout面试题分析)
- java中return与finally的执行顺序分析(根据字节码分析)
- Filter(五)FilterChain执行顺序
- Asp.net Mvc Framework 七 (Filter及其执行顺序)
- IT忍者神龟之Filter介绍,执行顺序,实例