当我们使用
@ControllerAdvice
和@ExceptionHandler
来全局捕获异常时,是否意味着spring内部使用了aop,也就是说spring会在内部创建一个切入点,匹配所有@Controller或@RestController修饰的方法,并且方面是@Around
还是@AfterThrowing
?
或者,没有这样的切入点,但是如果DispatcherServlet
中有这样的逻辑,如果遇到异常,就会交给对应的ExceptionHandler方法?
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
@ExceptionHandler(BaseException. class)
public ResponseEntity<?> handleAppException(BaseException ex, HttpServletRequest request) {
//...
}
@ExceptionHandler(value = ResourceNotFoundException. class)
public ResponseEntity<ErrorReponse> handleResourceNotFoundException(ResourceNotFoundException ex, HttpServletRequest request) {
//...
}
}
好像有这样的源码:
@Nullable
private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
List<Class<? extends Throwable>> matches = new ArrayList<>();
//Find all exception information that can be handled. MappedMethods stores the correspondence between exceptions and methods for handling exceptions
for (Class<? extends Throwable> mappedException : this. mappedMethods. keySet()) {
if (mappedException. isAssignableFrom(exceptionType)) {
matches. add(mappedException);
}
}
// If it is not empty, it means that there is a method to handle exceptions
if (!matches. isEmpty()) {
// Sort by matching degree from small to large
matches. sort(new ExceptionDepthComparator(exceptionType));
// Return the method that handles the exception
return this.mappedMethods.get(matches.get(0));
}
else {
return null;
}
}
但是虽然这是一个寻找对应方法的方法,但并不代表没有定义切入点,那么全局catch异常是否使用了aop相关技术呢?全局捕获异常算aop吗,还是只是和spring mvc有关?
当我们使用
和@ControllerAdvice
来全局捕获异常时,是否意味着spring内部使用了aop,@ExceptionHandler
是和不是。注释中的名称部分“advice”显然是 AOP 术语参考,告诉您逻辑上它是使用 AOP 概念实现的,即在连接应用程序时扫描并缓存带有异常处理程序的控制器建议,然后在以后应用异常处理所必需的。
也就是说,spring会在里面创建一个切点,它匹配所有@Controller或@RestController修饰的方法,切面是
还是@Around
?@AfterThrowing
其实不然。如果您查看控制器 bean,您将不会在它们上看到任何已注册的 AOP 顾问程序。如果它们不是任何其他 Spring AOP 方面的目标,则也不会为它们创建动态代理,即使它们是控制器建议异常处理程序的目标。这一切都在 Spring 内部进行了连接。也许它可以使用真正的 AOP 方面来实现,类似于
@Transactional
的实现,但是除了历史原因之外,可能还有其他原因来硬连接它,可能是因为异常处理被认为是低级的事情,应该是内置于框架中。