springboot源码解析-管中窥豹系列之排序(五)

Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去。

我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot源码管中窥豹系列。

 简介

二、排序

前几节我们讲源码的时候,会遇到一些排序的问题,我们都避而不谈

比如获取initializer时的排序:

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = getClassLoader(); Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader)); List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); // 排序 AnnotationAwareOrderComparator.sort(instances); return instances; }

比如对runner排序:

private void callRunners(ApplicationContext context, ApplicationArguments args) { List<Object> runners = new ArrayList<>(); // (1) 找到ApplicationRunner的实现类,加到list里面 runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); // (2) 找到CommandLineRunner的实现类,加到list里面 runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); // (3) 排序 AnnotationAwareOrderComparator.sort(runners); // (4) 钩子回调 for (Object runner : new LinkedHashSet<>(runners)) { if (runner instanceof ApplicationRunner) { callRunner((ApplicationRunner) runner, args); } if (runner instanceof CommandLineRunner) { callRunner((CommandLineRunner) runner, args); } } }

我们来分析一下这个排序AnnotationAwareOrderComparator.sort(list)的源码。

三、源码解析 public static final AnnotationAwareOrderComparator INSTANCE = new AnnotationAwareOrderComparator(); public static void sort(List<?> list) { if (list.size() > 1) { list.sort(INSTANCE); } }

已new的AnnotationAwareOrderComparator对象作为参数,排序

list.sort(comparator)是jdk自带的排序, 通用的

default void sort(Comparator<? super E> c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator<E> i = this.listIterator(); for (Object e : a) { i.next(); i.set((E) e); } }

我们知道排序要么实现Comparable接口,要么new Comparator, spring用的第二种

我们重点看下这个comparator : AnnotationAwareOrderComparator

public class AnnotationAwareOrderComparator extends OrderComparator { ... } public class OrderComparator implements Comparator<Object> { ... }

compare方法在OrderComparator里面:

@Override public int compare(@Nullable Object o1, @Nullable Object o2) { return doCompare(o1, o2, null); } 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); }

先判断有没有实现PriorityOrdered接口,实现了的比没实现的有高优先级

再用getOrder()判断

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()) { 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)); }

sourceProvider为空,我们可以直接看最后一行。

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

判断有没有实现Ordered接口,如果有就取出来它的order值

如果没有,就取Integer.MAX_VALUE

注意,order值越小,优先级越高

注意,上面findOrder方法是protected, 我们最开始说的AnnotationAwareOrderComparator对它进行了重写

@Override @Nullable protected Integer findOrder(Object obj) { Integer order = super.findOrder(obj); if (order != null) { return order; } return findOrderFromAnnotation(obj); } @Nullable private Integer findOrderFromAnnotation(Object obj) { AnnotatedElement element = (obj instanceof AnnotatedElement ? (AnnotatedElement) obj : obj.getClass()); MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY); Integer order = OrderUtils.getOrderFromAnnotations(element, annotations); if (order == null && obj instanceof DecoratingProxy) { return findOrderFromAnnotation(((DecoratingProxy) obj).getDecoratedClass()); } return order; }

先调用父类的findOrder方法

没找到,再调用findOrderFromAnnotation方法

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

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