SpringBoot中的排序

包含三个类

AnnotationAwareOrderComparator

OrderComparator

Comparator

类图如下:


image-20200421180701888.png

步骤1:排序调用OrderComparator的compare方法

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

步骤2:调用内部方法doCompare,先判断是否有一个实现PriorityOrdered接口,如果有一个实现,顺序关系可以确定直接返回。

如果都没有实现或者都实现了PriorityOrdered接口,进一步调用getOder方法返回排序值,然后确定顺序关系。

private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
    // 实现了PriorityOrdered接口,排序靠前
    // PriorityOrdered继承自Ordered接口,也可以实现getOrder方法,所以实现PriorityOrdered的类里面getOrder越小的越靠前
   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);
}

步骤3:内部方法getOrder,在OrderSourceProvider为null的情况下,直接调用了getOder重构方法

private int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) {
   Integer order = null;
    //OrderSourceProvider这里不做分析
   if (obj != null && sourceProvider != null) {
      Object orderSource = sourceProvider.getOrderSource(obj);
      if (orderSource != null) {
         if (orderSource.getClass().isArray()) {
            Object[] sources = ObjectUtils.toObjectArray(orderSource);
            for (Object source : sources) {
               order = findOrder(source);
               if (order != null) {
                  break;
               }
            }
         }
         else {
            order = findOrder(orderSource);
         }
      }
   }
   return (order != null ? order : getOrder(obj));
}

步骤4:getOder里面调用了findOrder方法,findOrder返回null的时候直接返回最小排序值

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

步骤5:AnnotationAwareOrderComparator重写findOrder方法

//AnnotationAwareOrderComparator重写findOrder方法
@Override
@Nullable
protected Integer findOrder(Object obj) {
    // 先调用父类方法,判断是否实现了Ordered接口,如果实现了调用getOrder方法,否则返回null
   Integer order = super.findOrder(obj);
   if (order != null) {
      return order;
   }
    // 如果没有实现Ordered接口,或者实现了Ordered接口但是getOrder返回null,则调用该方法
   return findOrderFromAnnotation(obj);
}

// 父类OrderComparator的findOrder方法
@Nullable
protected Integer findOrder(Object obj) {
    return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
}

步骤6:AnnotationAwareOrderComparator核心方法

@Nullable
private Integer findOrderFromAnnotation(Object obj) {
    // AnnotatedElement代表了在当前JVM中的一个“被注解元素”(可以是Class,Method,Field,Constructor,Package等
   AnnotatedElement element = (obj instanceof AnnotatedElement ? (AnnotatedElement) obj : obj.getClass());
    // MergedAnnotations是Spring的工具类,from方法是从element中获取注解,SearchStrategy是注解扫描策略,TYPE_HIERARCHY包含superclass,接口
   MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY);
    // 根据注解解析order
   Integer order = OrderUtils.getOrderFromAnnotations(element, annotations);
    // 如果order为null,并且排序对象实现了DecoratingProxy,则从代理类中获取排序order
   if (order == null && obj instanceof DecoratingProxy) {
      return findOrderFromAnnotation(((DecoratingProxy) obj).getDecoratedClass());
   }
   return order;
}

步骤7:OrderUtils方法

@Nullable
static Integer getOrderFromAnnotations(AnnotatedElement element, MergedAnnotations annotations) {
    // 如果注解元素不是一个类,每次都从注解中获取order
   if (!(element instanceof Class)) {
      return findOrder(annotations);
   }
    // 缓存中存在该类,从缓存中获取排序
   Object cached = orderCache.get(element);
   if (cached != null) {
      return (cached instanceof Integer ? (Integer) cached : null);
   }
    // 缓存不存在,就重新解析,并保存到缓存中
   Integer result = findOrder(annotations);
   orderCache.put(element, result != null ? result : NOT_ANNOTATED);
   return result;
}

@Nullable
private static Integer findOrder(MergedAnnotations annotations) {
    // 如果改元素上存在Order注解,则返回value值
   MergedAnnotation orderAnnotation = annotations.get(Order.class);
   if (orderAnnotation.isPresent()) {
      return orderAnnotation.getInt(MergedAnnotation.VALUE);
   }
    // 如果不存在Order注解,但是存在javax.annotation.Priority注解,则返回该注解的value值
   MergedAnnotation priorityAnnotation = annotations.get(JAVAX_PRIORITY_ANNOTATION);
   if (priorityAnnotation.isPresent()) {
      return priorityAnnotation.getInt(MergedAnnotation.VALUE);
   }
    // 如果注解都不存在,则返回null
   return null;
}

总结:

两个对象比较,排序规则调用判断顺序如下:

  1. 其中有一个实现了PriorityOrdered,则排序靠前,返回排序状态。如果都没有实现PriorityOrdered接口,或者都实现了PriorityOrdered接口,继续往下执行

  2. 分别获取两个对象的排序值,根据排序值确定排序状态

  3. 如果实现了PriorityOrdered或者Ordered接口,调用getOrder方法返回排序值。如果没有实现这两个接口或者getOrder方法返回null,继续往下执行

  4. 如果有Order注解,返回注解的value值作为排序值

  5. 如果有Priority注解,返回value值作为排序值

  6. 如果都没有,返回最小排序值

你可能感兴趣的:(SpringBoot中的排序)