包含三個(gè)類
AnnotationAwareOrderComparator
OrderComparator
Comparator
類圖如下:
步驟1:排序調(diào)用OrderComparator的compare方法
public int compare(@Nullable Object o1, @Nullable Object o2) {
return doCompare(o1, o2, null);
}
步驟2:調(diào)用內(nèi)部方法doCompare贵白,先判斷是否有一個(gè)實(shí)現(xiàn)PriorityOrdered接口,如果有一個(gè)實(shí)現(xiàn)崩泡,順序關(guān)系可以確定直接返回禁荒。
如果都沒(méi)有實(shí)現(xiàn)或者都實(shí)現(xiàn)了PriorityOrdered接口,進(jìn)一步調(diào)用getOder方法返回排序值角撞,然后確定順序關(guān)系呛伴。
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
// 實(shí)現(xiàn)了PriorityOrdered接口,排序靠前
// PriorityOrdered繼承自O(shè)rdered接口靴寂,也可以實(shí)現(xiàn)getOrder方法,所以實(shí)現(xiàn)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:內(nèi)部方法getOrder召耘,在OrderSourceProvider為null的情況下百炬,直接調(diào)用了getOder重構(gòu)方法
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里面調(diào)用了findOrder方法,findOrder返回null的時(shí)候直接返回最小排序值
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) {
// 先調(diào)用父類方法污它,判斷是否實(shí)現(xiàn)了Ordered接口剖踊,如果實(shí)現(xiàn)了調(diào)用getOrder方法,否則返回null
Integer order = super.findOrder(obj);
if (order != null) {
return order;
}
// 如果沒(méi)有實(shí)現(xiàn)Ordered接口衫贬,或者實(shí)現(xiàn)了Ordered接口但是getOrder返回null德澈,則調(diào)用該方法
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代表了在當(dāng)前JVM中的一個(gè)“被注解元素”(可以是Class,Method固惯,F(xiàn)ield梆造,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);
// 根據(jù)注解解析order
Integer order = OrderUtils.getOrderFromAnnotations(element, annotations);
// 如果order為null忽肛,并且排序?qū)ο髮?shí)現(xiàn)了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) {
// 如果注解元素不是一個(gè)類烂斋,每次都從注解中獲取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<Order> 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;
}
總結(jié):
兩個(gè)對(duì)象比較,排序規(guī)則調(diào)用判斷順序如下:
其中有一個(gè)實(shí)現(xiàn)了PriorityOrdered图张,則排序靠前锋拖,返回排序狀態(tài)诈悍。如果都沒(méi)有實(shí)現(xiàn)PriorityOrdered接口,或者都實(shí)現(xiàn)了PriorityOrdered接口兽埃,繼續(xù)往下執(zhí)行
分別獲取兩個(gè)對(duì)象的排序值侥钳,根據(jù)排序值確定排序狀態(tài)
如果實(shí)現(xiàn)了PriorityOrdered或者Ordered接口,調(diào)用getOrder方法返回排序值柄错。如果沒(méi)有實(shí)現(xiàn)這兩個(gè)接口或者getOrder方法返回null舷夺,繼續(xù)往下執(zhí)行
如果有Order注解,返回注解的value值作為排序值
如果有Priority注解售貌,返回value值作為排序值
如果都沒(méi)有给猾,返回最小排序值