以下源码解析内容以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)