Controller Advice

通常,@ExceptionHandler@InitBinder@ModelAttribute 方法在其宣告所在的 @Controller 類(或類層級)內生效。如果您希望這些方法更全域性地生效(跨越多個 controller),可以在使用 @ControllerAdvice@RestControllerAdvice 註解的類中宣告它們。

@ControllerAdvice 使用 @Component 進行註解,這意味著此類可以透過元件掃描註冊為 Spring Bean。@RestControllerAdvice 是一個組合註解,它同時使用了 @ControllerAdvice@ResponseBody 註解,這本質上意味著 @ExceptionHandler 方法會透過訊息轉換(而非檢視解析或模板渲染)渲染到響應體中。

在啟動時,用於 @RequestMapping@ExceptionHandler 方法的基礎設施類會檢測使用 @ControllerAdvice 註解的 Spring Bean,然後在執行時應用它們的方法。全域性 @ExceptionHandler 方法(來自 @ControllerAdvice)在區域性方法(來自 @Controller之後 應用。相比之下,全域性 @ModelAttribute@InitBinder 方法在區域性方法 之前 應用。

預設情況下,@ControllerAdvice 方法應用於每個請求(即所有 controller),但您可以透過使用註解上的屬性將其範圍縮小到 controller 的子集,如下例所示

  • 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。