diff --git a/spring/Spring core/SpringMVC.md b/spring/Spring core/SpringMVC.md index 5c8cd96..256a077 100644 --- a/spring/Spring core/SpringMVC.md +++ b/spring/Spring core/SpringMVC.md @@ -627,6 +627,28 @@ public ResponseEntity handle(Exception ex) { 上述两种写法的区别是: 1. 如果参数类型为IOException,那么当cause exception为FileSystemException或RemoteException,且root exception为IOException时,实际的cause exception要通过ex.getCause来获取 2. 如果参数类型为Exception,那么当cause exception为FileSystemException或RemoteException且root exception不为指定类型异常时,指定类型异常统一都通过ex.getCause来获取 +> 通常情况下,@ExceptionHandler方法的参数类型应该尽可能的具体,而且推荐将一个宽泛的@ExceptionHandler拆分成多个独立的@ExceptionHandler方法,每个方法负责处理特定类型的异常。 +**对于@ExceptionHandler方法,在捕获异常之后可以对异常进行rethrow操作,重新抛出之后的异常会在剩余的resolution chain中传播,就好像给定的@ExceptionHandler在开始就没有匹配** +### Controller +对于@ModelAttribute、@InitBinder、@ExceptionHandler注解,若其在@Controller类中使用,那么该类仅对其所在的@Controller类有效。 +**如果这些注解定义在@ControllerAdvice或@RestControllerAdvice类中,那么它们对所有的@Controller类都有效。** +**位于@ControllerAdvice类中的@ExceptionHandler方法,其可以用于处理任何@Controller类中抛出的异常或任何其他exception handler中抛出的异常。** +> 对于@ControllerAdvice中的@ExceptionHandler方法,其会在其他所有位于@Controller类中的@ExceptionHandler方法执行完**之后**才会执行;而@InitBinder和@ModelAttribute方法,则是位于@ControllerAdive方法中的**优先于**位于@Controller类中的执行 +> +@ControllerAdive使用如下: +```java +// 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 {} +```