控制器建議
通常,@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
// Target all Controllers annotated with @RestController
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}
// Target all Controllers within specific packages
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// Target all Controllers assignable to specific classes
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}
// Target all Controllers annotated with @RestController
@ControllerAdvice(annotations = [RestController::class])
public class ExampleAdvice1 {}
// Target all Controllers within specific packages
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}
// Target all Controllers assignable to specific classes
@ControllerAdvice(assignableTypes = [ControllerInterface::class, AbstractController::class])
public class ExampleAdvice3 {}
上述示例中的選擇器在執行時進行評估,如果大量使用,可能會對效能產生負面影響。有關更多詳細資訊,請參閱 @ControllerAdvice javadoc。