Presort beans in ControllerAdviceBean.findAnnotatedBeans()

Prior to this commit, all clients of
ControllerAdviceBean.findAnnotatedBeans() sorted the returned list
manually. In addition, clients within the core Spring Framework
unnecessarily used AnnotationAwareOrderComparator instead of
OrderComparator to sort the list.

This commit presorts the ControllerAdviceBean list using OrderComparator
directly within ControllerAdviceBean.findAnnotatedBeans().

Closes gh-23188
This commit is contained in:
Sam Brannen
2019-06-24 14:48:18 +03:00
parent dd15ff79d7
commit d0231cb29a
7 changed files with 96 additions and 32 deletions

View File

@@ -34,17 +34,18 @@ import org.springframework.stereotype.Component;
*
* <p>Classes annotated with {@code @ControllerAdvice} can be declared explicitly
* as Spring beans or auto-detected via classpath scanning. All such beans are
* sorted based on {@link org.springframework.core.Ordered Ordered} /
* {@link org.springframework.core.PriorityOrdered PriorityOrdered} semantics or
* sorted based on {@link org.springframework.core.Ordered Ordered} semantics or
* {@link org.springframework.core.annotation.Order @Order} /
* {@link javax.annotation.Priority @Priority} declarations, with {@code Ordered} /
* {@code PriorityOrdered} semantics taking precedence over {@code @Order} /
* {@code @Priority} declarations. {@code @ControllerAdvice} beans are then
* applied in that order at runtime. For handling exceptions, an
* {@code @ExceptionHandler} will be picked on the first advice with a matching
* exception handler method. For model attributes and {@code InitBinder}
* initialization, {@code @ModelAttribute} and {@code @InitBinder} methods will
* also follow {@code @ControllerAdvice} order.
* {@link javax.annotation.Priority @Priority} declarations, with {@code Ordered}
* semantics taking precedence over {@code @Order} / {@code @Priority} declarations.
* {@code @ControllerAdvice} beans are then applied in that order at runtime.
* Note, however, that {@code @ControllerAdvice} beans that implement
* {@link org.springframework.core.PriorityOrdered PriorityOrdered} are <em>not</em>
* given priority over {@code @ControllerAdvice} beans that implement {@code Ordered}.
* For handling exceptions, an {@code @ExceptionHandler} will be picked on the
* first advice with a matching exception handler method. For model attributes
* and {@code InitBinder} initialization, {@code @ModelAttribute} and
* {@code @InitBinder} methods will also follow {@code @ControllerAdvice} order.
*
* <p>Note: For {@code @ExceptionHandler} methods, a root exception match will be
* preferred to just matching a cause of the current exception, among the handler

View File

@@ -22,6 +22,7 @@ import java.util.List;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.OrderUtils;
@@ -215,6 +216,11 @@ public class ControllerAdviceBean implements Ordered {
* Find beans annotated with {@link ControllerAdvice @ControllerAdvice} in the
* given {@link ApplicationContext} and wrap them as {@code ControllerAdviceBean}
* instances.
* <p>As of Spring Framework 5.2, the {@code ControllerAdviceBean} instances
* in the returned list are sorted using {@link OrderComparator#sort(List)}.
* @see #getOrder()
* @see OrderComparator
* @see Ordered
*/
public static List<ControllerAdviceBean> findAnnotatedBeans(ApplicationContext context) {
List<ControllerAdviceBean> adviceBeans = new ArrayList<>();
@@ -226,6 +232,7 @@ public class ControllerAdviceBean implements Ordered {
adviceBeans.add(new ControllerAdviceBean(name, context, controllerAdvice));
}
}
OrderComparator.sort(adviceBeans);
return adviceBeans;
}