控制器建议
通常,@ExceptionHandler
、@InitBinder
和@ModelAttribute
方法适用于声明它们的@Controller
类(或类层次结构)内。如果您希望这些方法在更广泛的范围内适用(跨控制器),可以在一个使用@ControllerAdvice
或@RestControllerAdvice
注解的类中声明它们。
@ControllerAdvice
使用@Component
注解,这意味着这样的类可以通过组件扫描注册为Spring bean。 @RestControllerAdvice
是一个组合注解,它同时使用@ControllerAdvice
和@ResponseBody
注解,这基本上意味着@ExceptionHandler
方法通过消息转换呈现到响应体中(而不是视图解析或模板渲染)。
在启动时,@RequestMapping
和@ExceptionHandler
方法的基础设施类会检测使用@ControllerAdvice
注解的Spring bean,然后在运行时应用它们的方法。全局@ExceptionHandler
方法(来自@ControllerAdvice
)会在本地方法(来自@Controller
)之后应用。相比之下,全局@ModelAttribute
和@InitBinder
方法会在本地方法之前应用。
默认情况下,@ControllerAdvice
方法适用于每个请求(即所有控制器),但您可以通过注解上的属性将其缩小到控制器的子集,如下例所示:
-
Java
-
Kotlin
// 目标是所有使用@RestController注解的控制器
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}
// 目标是特定包内的所有控制器
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// 目标是可分配给特定类的所有控制器
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}
// 目标是所有使用@RestController注解的控制器
@ControllerAdvice(annotations = [RestController::class])
public class ExampleAdvice1 {}
// 目标是特定包内的所有控制器
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// 目标是可分配给特定类的所有控制器
@ControllerAdvice(assignableTypes = [ControllerInterface::class, AbstractController::class])
public class ExampleAdvice3 {}
上述示例中的选择器在运行时进行评估,如果广泛使用可能会对性能产生负面影响。请查看@ControllerAdvice
javadoc以获取更多详细信息。