Order接口的排序逻辑

OrderComparator 的排序逻辑

  1. OrderComparator 实现了 Comparator 接口,重写 compare() 方法

  2. compare() 方法内部仅仅是调用了 doCompare() 方法,因此 doCompare() 方法的排序规则即为 compare() 方法的排序规则

  3. 接下来是对于 compare(o1,o2) 本身的讨论

    对于任何排序来说,我们假定只有唯一一条本质的排序规则:优先级(weight)高的排在前面

    而其它各种自定义的排序规则(比较器)被认为是该规则的具体化。例如,对数字的升序排序,可以认为是数值小的优先级高;对数字的降序排序,可以认为是数值大的优先级高。在当前的假设下,compare() 的设计者对方法的约定为:当 o1 的优先级比 o2 高时,compare(o1, o2) 的返回值为负;当 o1 的优先级比 o2 低时,compare(o1, o2) 的返回值为正。(充要条件,前推后,后推前)

  4. 最后回到 doCompare() 本身上来,实现逻辑为:

    • 如果是 PriorityOrder 类型,那么拥有更高的优先级(weight)
    • 如果类型相同,那么 order 值越小,优先级(weight)越高。没有 order 值的按 order = Integer.MAX_VALUE 处理
public class OrderComparator implements Comparator<Object> {
    public static final OrderComparator INSTANCE = new OrderComparator();
    public Comparator<Object> withSourceProvider(OrderSourceProvider sourceProvider) {
        return (o1, o2) -> doCompare(o1, o2, sourceProvider);
    }

    @Override
    public int compare(@Nullable Object o1, @Nullable Object o2) {
        return doCompare(o1, o2, null);
    }

    // 1. PriorityOrdered 比 Order 拥有更高的优先级 (o1拥有更高优先级, 但是doCompore(o1,o2)的返回值是-1)
    private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
        boolean p1 = (o1 instanceof PriorityOrdered);
        boolean p2 = (o2 instanceof PriorityOrdered);
        if (p1 && !p2) {
            return -1;
        }else if (p2 && !p1) {
            return 1;
        }

        int i1 = getOrder(o1, sourceProvider);
        int i2 = getOrder(o2, sourceProvider);
        return Integer.compare(i1, i2);
    }

    private int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) {
        Integer order = null;
        if (obj != null && sourceProvider != null) {
            Object orderSource = sourceProvider.getOrderSource(obj);
            if (orderSource != null) {
                if (orderSource.getClass().isArray()) {
                    for (Object source : ObjectUtils.toObjectArray(orderSource)) {
                        order = findOrder(source);
                        if (order != null) {
                            break;
                        }
                    }
                }
                else {
                    order = findOrder(orderSource);
                }
            }
        }
        return (order != null ? order : getOrder(obj));
    }

    protected int getOrder(@Nullable Object obj) {
        if (obj != null) {
            Integer order = findOrder(obj);
            if (order != null) {
                return order;
            }
        }
        return Ordered.LOWEST_PRECEDENCE;
    }

    @Nullable
    protected Integer findOrder(Object obj) {
        return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
    }

    @Nullable
    public Integer getPriority(Object obj) {
        return null;
    }

    public static void sort(List<?> list) {
        if (list.size() > 1) {
            list.sort(INSTANCE);
        }
    }

    public static void sort(Object[] array) {
        if (array.length > 1) {
            Arrays.sort(array, INSTANCE);
        }
    }

    public static void sortIfNecessary(Object value) {
        if (value instanceof Object[]) {
            sort((Object[]) value);
        }
        else if (value instanceof List) {
            sort((List<?>) value);
        }
    }

    @FunctionalInterface
    public interface OrderSourceProvider {
        @Nullable
        Object getOrderSource(Object obj);
    }

}

   转载规则


《Order接口的排序逻辑》 熊水斌 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
@ComponentScan 组件扫描的实现逻辑 通过 AnnotationUtils.findAnnotation() 来获取该注解的信息(注解信息主要是扫描的包,以及配置类中是否包含该注解) 解析并拼接转换字符串(从设置的包名到实际的文
2023-04-14
下一篇 
Bean的生命周期 Bean的生命周期
Bean 的生命周期执行顺序: 无参构造函数 依赖注入(包括属性注入) 初始化方法 销毁方法 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spr
2023-04-13
  目录