2

我有一个 Spring 4 应用程序,其中包含多个用 @Order(someValue) 注释的 ControllerAdvice。此外,我在我的一个外部库中发现了一个 ControllerAdvice,它也用@Order(someValue) 进行了注释。

我的理解是,当控制器抛出异常时,ControllerAdvices 的顺序决定了在 ControllerAdvices 中搜索该特定异常的顺序。我现在认为在我的外部库中也可能有其他带有 @Order 注释的 ControllerAdvices。但是,我无法下载所有库并搜索所有 ControllerAdvices 并检查它们的 Order 值。

如果我希望它在其他 ControllerAdvice 之前捕获异常,我如何知道在特定 ControllerAdvice 上放置什么 Order 值?我应该为我的用例使用不同的方法吗?

请参阅下面的代码。

我希望 ExceptionHandlerControllerTwo 在 ExceptionHandlerControllerOne 之后和 ExceptionHandlerControllerThree 之前捕获异常。

我为 ExceptionHandlerControllerTwo 尝试了不同的 Order 值。数字 1 到 90 似乎以我想要的方式捕获异常。我的外部库中可能还有其他我不知道的 ControllerAdvice。

在我的应用程序中:

@ControllerAdvice
@Order(0)
public class ExceptionHandlerControllerOne {
   // multiple @ExceptionHandler methods
}
@ControllerAdvice
@Order(80)
public class ExceptionHandlerControllerTwo {
   // multiple @ExceptionHandler methods
}
@ControllerAdvice
@Order(90)
public class ExceptionHandlerControllerThree {
   // multiple @ExceptionHandler methods
}

在外部库中:

@ControllerAdvice
@Order(100)
@Slf4j
public class CatchAllExceptionHandlerController {
   // multiple @ExceptionHandler methods
}
4

2 回答 2

0

您可以尝试查找所有@ControllerAdvice带注释的 bean,并根据结果定义顺序。要查找订单,您可以使用以下内容:

ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(ControllerAdvice.class));
scanner.findCandidateComponents("org.example") // Change the package name
        .stream()
        .filter(AnnotatedBeanDefinition.class::isInstance)
        .map(AnnotatedBeanDefinition.class::cast)
        .forEach(annotatedBeanDefinition -> {
            System.out.println(
                    annotatedBeanDefinition.getBeanClassName() + ": " +
                    annotatedBeanDefinition.getMetadata().getAllAnnotationAttributes(Order.class.getName())
            );
        });
于 2019-10-08T23:41:12.083 回答
-1

@Order(Ordered.HIGHEST_PRECEDENCE) 可以解决问题,它会告诉框架首先运行标记为 HIGHEST_PRECEDENCE 的建议。

于 2019-10-09T01:54:26.820 回答