详解Spring的核心排序类-AnnotationAwareOrderComparator

以下源码解析内容以Spring5.2.8-RELEASE作为依据进行源码分析

AnnotationAwareOrderComparator是什么

AnnotationAwareOrderComparator是Spring内部的核心排序组件,熟悉Spring的小伙伴应该都不会陌生,通过这个类,可以对实现了PriorityOrdered、Ordered以及被@Order注解修饰的类进行统一的排序。Spring在内部启动时,对很多组件都设置过排序数值以便能顺利进行排序。如AbstractApplicationContext#refresh()中对BeanPostProcessor、BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor都是经过排序后才启动的;又如SpringBoot中的条件注解ConditionalOnClass、ConditionalOnBean、ConditionalOnProperty等都是通过设置Condition的排序值进行排序的,若不进行排序,试想即便是配置了ConditionalOnBean,但是却无法加载到对应的class,那加载bean也没有意义。
在进行源码分析之前,如果对一些基本类、注解有一定了解,那么就更容易理解AnnotationAwareOrderComparator的排序原理了。

主要排序组件类介绍

OrderComparator:排序器基类,实现了Comparator,排序规则仅支持PriorityOrdered、Ordered,不支持@Order。
AnnotationAwareOrderComparator:继承自OrderComparator,在OrderComparator排序的基础上,增加了对排序类的@Order注解的支持,但是若即实现Ordered接口,又有@Order注解时,则优先从接口实现中获取值。
实现原理主要还是覆写了OrderComparator#findOrder,增加了从注解中获取order的方法。
Ordered:排序接口,内有getOrder,用于给实现类返回自己的order;还有两个优先级的常量HIGHEST_PRECEDENCE(Integer.MIN_VALUE)、LOWEST_PRECEDENCE(Integer.MAX_VALUE)。
PriorityOrdered:继承自Ordered,但是没有扩展任何方法,可以被视为一个标记。
Order:即@Order,是spring的注解,其value就是配置的order。
javax.annotation.Priority:即@Priority,javax的规范注解,其value就是配置的order
排序数字:比较规则-越小的数字优先级越高,越大的数字优先级越低。
可见Ordered

	/**
	 * Useful constant for the highest precedence value.
	 * @see java.lang.Integer#MIN_VALUE
	 */
    // 最高的优先级,实际数值为Integer的最小值
	int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;

	/**
	 * Useful constant for the lowest precedence value.
	 * @see java.lang.Integer#MAX_VALUE
	 */
    // 最低的优先级,实际数值为Integer的最大值
	int LOWEST_PRECEDENCE = Integer.MAX_VALUE;

AnnotationAwareOrderComparator源码解析

AnnotationAwareOrderComparator继承自OrderComparator,而OrderComparator则直接实现了Comparator,所以入口就在OrderComparator#compare中。

    public int compare(@Nullable Object o1, @Nullable Object o2) {
        // 调用内部的私有方法doCompare
		return doCompare(o1, o2, null);
	}
	private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
		// 优先PriorityOrdered
		boolean p1 = (o1 instanceof PriorityOrdered);
		boolean p2 = (o2 instanceof PriorityOrdered);
		// p1实现了PriorityOrdered,但是p2没实现PriorityOrdered,则p1优先级更高
		if (p1 && !p2) {
			return -1;
		}
		// p1没实现了PriorityOrdered,但是p2实现了PriorityOrdered,则p2优先级更高
		else if (p2 && !p1) {
			return 1;
		}

		// 方法执行到此,说明两者要么都实现了PriorityOrdered,或者都没实现PriorityOrdered,则此时不再比较PriorityOrdered,开始比较Order
		// 调用内部私有方法getOrder
		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;
		// 由于doCompare方法传入的第二个参数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);
				}
			}
		}
		// 直接执行这里的,调用getOrder继续获取order
		return (order != null ? order : getOrder(obj));
	}
	protected int getOrder(@Nullable Object obj) {
		if (obj != null) {
			// 调用findOrder从对象中获取order,该方法在AnnotationAwareOrderComparator中被覆写了
			Integer order = findOrder(obj);
			if (order != null) {
				return order;
			}
		}
		// 获取不到,则说明对象类没有实现Ordered,且没有@Order注解,默认最低优先级
		return Ordered.LOWEST_PRECEDENCE;
	}

findOrder方法是定义在OrderComparator中的,但是子类AnnotationAwareOrderComparator又进行了覆写。

先看看父类OrderComparator#findOrder方法

	protected Integer findOrder(Object obj) {
		// 可以看出仅仅只是从实现Ordered接口入手,获取其getOrder的值
		return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
	}

再看看子类覆写的AnnotationAwareOrderComparator#findOrder

	protected Integer findOrder(Object obj) {
		// 优先调用父类OrderComparator#findOrder,即从Ordered接口入手,获取其getOrder的值
		Integer order = super.findOrder(obj);
		if (order != null) {
			return order;
		}
		// 获取不到时,再调用内部私有方法findOrderFromAnnotation从注解获取order
		return findOrderFromAnnotation(obj);
	}
	private Integer findOrderFromAnnotation(Object obj) {
		AnnotatedElement element = (obj instanceof AnnotatedElement ? (AnnotatedElement) obj : obj.getClass());
		MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY);
		// 从@Order注解中获取order值,该方法会将class作为缓存key放入缓存map中,即同一个类第二次无需再读取注解的值
		Integer order = OrderUtils.getOrderFromAnnotations(element, annotations);
		if (order == null && obj instanceof DecoratingProxy) {
			return findOrderFromAnnotation(((DecoratingProxy) obj).getDecoratedClass());
		}
		return order;
	}

可以看出,内部是通过工具类OrderUtils获取排序注解的值

	static Integer getOrderFromAnnotations(AnnotatedElement element, MergedAnnotations annotations) {
		// 由findOrderFromAnnotation可知,传入的必然是class对象
		if (!(element instanceof Class)) {
			return findOrder(annotations);
		}
		// 从缓存中以AnnotatedElement(此处为class)作为缓存key,获取order
		Object cached = orderCache.get(element);
		if (cached != null) {
			// 缓存不为空,直接返回order
			return (cached instanceof Integer ? (Integer) cached : null);
		}
		// 缓存为空,调用内部私有方法findOrder继续获取order
		Integer result = findOrder(annotations);
		// 将得到的order以key-AnnotatedElement,value-order放入缓存map中,若result即order为空,则放入NOT_ANNOTATED(其实就是一个new Object())作为获取失败的
		orderCache.put(element, result != null ? result : NOT_ANNOTATED);
		return result;
	}
	private static Integer findOrder(MergedAnnotations annotations) {
		// 优先从@Order注解中获取order,获取成功直接返回其value
		MergedAnnotation<Order> orderAnnotation = annotations.get(Order.class);
		if (orderAnnotation.isPresent()) {
			return orderAnnotation.getInt(MergedAnnotation.VALUE);
		}
		// 用于获取@Priority注解的value(即javax.annotation.Priority)
		MergedAnnotation<?> priorityAnnotation = annotations.get(JAVAX_PRIORITY_ANNOTATION);
		if (priorityAnnotation.isPresent()) {
			return priorityAnnotation.getInt(MergedAnnotation.VALUE);
		}
		return null;
	}

总结

1、实现PriorityOrdered优先级更高,都有PriorityOrdered则比较各自的order(PriorityOrdered其实只是一个标记,虽然它继承自Ordered,但是没有扩展任何方法)
2、都没有PriorityOrdered,则比较Ordered#getOrder、@Order#value以及javax.annotation.Priority,值小的优先级更高
(此时,优先获取接口的Ordered#getOrder,若有则不再获取注解的@Order#value,若没有再获取注解@Order#value的值,若依然没有则尝试获取javax.annotation.Priority的值,都没有则默认返回最低优先级Ordered.LOWEST_PRECEDENCE)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值