diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAwareOrderComparator.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAwareOrderComparator.java index ca496f8f363d..79bf0716921a 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAwareOrderComparator.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAwareOrderComparator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,12 @@ package org.springframework.core.annotation; import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; import org.springframework.core.DecoratingProxy; import org.springframework.core.OrderComparator; +import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; import org.springframework.lang.Nullable; /** @@ -61,35 +61,23 @@ public class AnnotationAwareOrderComparator extends OrderComparator { @Override @Nullable protected Integer findOrder(Object obj) { - // Check for regular Ordered interface Integer order = super.findOrder(obj); if (order != null) { return order; } + return findOrderFromAnnotation(obj); + } - // Check for @Order and @Priority on various kinds of elements - if (obj instanceof Class) { - return OrderUtils.getOrder((Class) obj); - } - else if (obj instanceof Method) { - Order ann = AnnotationUtils.findAnnotation((Method) obj, Order.class); - if (ann != null) { - return ann.value(); - } + private Integer findOrderFromAnnotation(Object obj) { + AnnotatedElement element = obj instanceof AnnotatedElement + ? (AnnotatedElement) obj + : obj.getClass(); + MergedAnnotations annotations = MergedAnnotations.from(element, + SearchStrategy.EXHAUSTIVE); + Integer order = OrderUtils.getOrderFromAnnotations(element, annotations); + if (order == null && obj instanceof DecoratingProxy) { + return findOrderFromAnnotation(((DecoratingProxy) obj).getDecoratedClass()); } - else if (obj instanceof AnnotatedElement) { - Order ann = AnnotationUtils.getAnnotation((AnnotatedElement) obj, Order.class); - if (ann != null) { - return ann.value(); - } - } - else { - order = OrderUtils.getOrder(obj.getClass()); - if (order == null && obj instanceof DecoratingProxy) { - order = OrderUtils.getOrder(((DecoratingProxy) obj).getDecoratedClass()); - } - } - return order; } @@ -106,8 +94,8 @@ public Integer getPriority(Object obj) { return OrderUtils.getPriority((Class) obj); } Integer priority = OrderUtils.getPriority(obj.getClass()); - if (priority == null && obj instanceof DecoratingProxy) { - priority = OrderUtils.getPriority(((DecoratingProxy) obj).getDecoratedClass()); + if (priority == null && obj instanceof DecoratingProxy) { + return getPriority(((DecoratingProxy) obj).getDecoratedClass()); } return priority; } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/OrderUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/OrderUtils.java index 29fea2133b24..5064fd386413 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/OrderUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/OrderUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ package org.springframework.core.annotation; -import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; import java.util.Map; +import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; import org.springframework.util.ConcurrentReferenceHashMap; /** @@ -33,33 +33,15 @@ * @see Order * @see javax.annotation.Priority */ -@SuppressWarnings("unchecked") public abstract class OrderUtils { /** Cache marker for a non-annotated Class. */ private static final Object NOT_ANNOTATED = new Object(); - - @Nullable - private static Class priorityAnnotationType; - - static { - try { - priorityAnnotationType = (Class) - ClassUtils.forName("javax.annotation.Priority", OrderUtils.class.getClassLoader()); - } - catch (Throwable ex) { - // javax.annotation.Priority not available - priorityAnnotationType = null; - } - } - + private static final String JAVAX_PRIORITY_ANNOTATION = "javax.annotation.Priority"; /** Cache for @Order value (or NOT_ANNOTATED marker) per Class. */ - private static final Map, Object> orderCache = new ConcurrentReferenceHashMap<>(64); - - /** Cache for @Priority value (or NOT_ANNOTATED marker) per Class. */ - private static final Map, Object> priorityCache = new ConcurrentReferenceHashMap<>(); + private static final Map orderCache = new ConcurrentReferenceHashMap<>(64); /** @@ -99,20 +81,41 @@ public static Integer getOrder(Class type, @Nullable Integer defaultOrder) { */ @Nullable public static Integer getOrder(Class type) { - Object cached = orderCache.get(type); + return getOrderFromAnnotations(type, MergedAnnotations.from(type, SearchStrategy.EXHAUSTIVE)); + } + + /** + * Return the order from the specified annotations collection. + *

Takes care of {@link Order @Order} and + * {@code @javax.annotation.Priority}. + * @param element the source element + * @param annotations the annotation to consider + * @return the order value, or {@code null} if none can be found + */ + static Integer getOrderFromAnnotations(AnnotatedElement element, + MergedAnnotations annotations) { + if (!(element instanceof Class)) { + return findOrder(annotations); + } + Object cached = orderCache.get(element); if (cached != null) { return (cached instanceof Integer ? (Integer) cached : null); } - Order order = AnnotationUtils.findAnnotation(type, Order.class); - Integer result; - if (order != null) { - result = order.value(); + Integer result = findOrder(annotations); + orderCache.put(element, result != null ? result : NOT_ANNOTATED); + return result; + } + + private static Integer findOrder(MergedAnnotations annotations) { + MergedAnnotation orderAnnotation = annotations.get(Order.class); + if (orderAnnotation.isPresent()) { + return orderAnnotation.getInt(MergedAnnotation.VALUE); } - else { - result = getPriority(type); + MergedAnnotation priorityAnnotation = annotations.get(JAVAX_PRIORITY_ANNOTATION); + if (priorityAnnotation.isPresent()) { + return priorityAnnotation.getInt(MergedAnnotation.VALUE); } - orderCache.put(type, (result != null ? result : NOT_ANNOTATED)); - return result; + return null; } /** @@ -123,20 +126,9 @@ public static Integer getOrder(Class type) { */ @Nullable public static Integer getPriority(Class type) { - if (priorityAnnotationType == null) { - return null; - } - Object cached = priorityCache.get(type); - if (cached != null) { - return (cached instanceof Integer ? (Integer) cached : null); - } - Annotation priority = AnnotationUtils.findAnnotation(type, priorityAnnotationType); - Integer result = null; - if (priority != null) { - result = (Integer) AnnotationUtils.getValue(priority); - } - priorityCache.put(type, (result != null ? result : NOT_ANNOTATED)); - return result; + return MergedAnnotations.from(type, SearchStrategy.EXHAUSTIVE).get( + JAVAX_PRIORITY_ANNOTATION).getValue(MergedAnnotation.VALUE, + Integer.class).orElse(null); } }