一个排序引发的BUG (2)

Deprecated since 2.7.0

2.7.0 之后被废除。

那么就有点意思了,为啥被废除?

来,看个例子,还是刚刚的那个测试用例。

我就稍微的这么一改:

@Activate(before = "_2")
public class Filter5 implements Filter0{
}

改动点就是在 Filter5 上配置了:

@Activate(before = "_2")

含义就是 Filter5 在 “_2” 之前执行。

“_2” 是啥?

就是 Filter2 的一个映射而已:

一个排序引发的BUG

那么问题就来了,作为一个正常的程序猿,自信的对 Filter5 进行了这个改动之后,他内心的想法一定是想要把这样的 Filter 链:

Filter4 -> Filter3 -> Filter2 -> Filter1 -> Filter5

修改为这样:(Filter5 在 Filter2 之前执行):

Filter4 -> Filter3 -> Filter5 -> Filter2 -> Filter1

那么实际情况是怎样的呢?

来跑一把:

一个排序引发的BUG

咋回事?这不是我预期的执行链啊?

是的,这就是 BUG 的表现。

一个排序引发的BUG

咋回事啊?

到底是咋回事呢?

且听我给你分析一波。

上一小节我说了,问题出在排序算法上。

org.apache.dubbo.common.extension.support.ActivateComparator

来,一起看一下:

一个排序引发的BUG

首先标号为 ① 的地方就是把 before、after、order 封装了一下,然后提供了几个比较的方法。你知道 ActivateInfo 这个实体里面有这些东西就行了,后面的代码会用到。

然后说说标号为 ② 的地方。

这个地方你别看挺长的,但是其实逻辑特别简单,当前对比的两个 filter 中的任何一个配置了 before、after 就会进入到标号为 ② 的部分的逻辑。

然后这里面的一坨逻辑是的这样的:

一个排序引发的BUG

具体逻辑不细说了,等会给你来个直观的演示。

最后标号为 ③ 这个地方,有点意思,稍微多说几句。

能走到标号为 ③ 的地方,说明当前对比的两个 filter 都没有配置 after、before 这两个属性。

直接对比 Order 就行了。

这个地方对 Order 相等的情况还做了一个特殊处理:

o1.getSimpleName().compareTo(o2.getSimpleName()) > 0 ? 1 : -1

如果 Order 相等,再比较类名。

这样做的原因也是保证排序的稳定性。

举个例子,比如这两 Filter,都没有指定 Order:

一个排序引发的BUG

那如果我们去掉这个判断:

一个排序引发的BUG

代码就变成了这样:

if (a1.order > a2.order) {
    return 1 
else {
    return -1 
    
}

简化一下就是这样:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypsgd.html