Dubbo的Filter执行顺序分析

本文详细解析了Dubbo服务框架中过滤器(Filter)的调用顺序原理及其配置方式,阐述了如何通过设置Activate注解中的order属性来控制自定义过滤器的执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近用到了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.youkuaiyun.com/skiof007/article/details/51953497

转载于:https://my.oschina.net/u/3729778/blog/1612027

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值