Controller Advice

通常,@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 以取得更多詳細資訊。