When we use @ControllerAdvice
and @ExceptionHandler
to catch exceptions globally, does it mean that spring uses aop internally, that is to say, spring will create a cut point inside, which matches all @Controller or @RestController modified method, and the aspect is @Around
or @AfterThrowing
?
Or, there is no such cut point, but if there is such logic in DispatcherServlet
, if an exception is encountered, it will be handed over to the corresponding ExceptionHandler method?
@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) {
//...
}
}
It seems that there is such a source code:
@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;
}
}
But although this is a method to find the corresponding method, it does not mean that there is no defined cut point, so does the global catch exception use aop-related technology? Is global catching exceptions counted as aop, or is it just related to spring mvc?
When we use
@ControllerAdvice
and@ExceptionHandler
to catch exceptions globally, does it mean that spring uses aop internally,
Yes and no. The name part "advice" in the annotation, which clearly is an AOP terminology reference, tells you that logically it is implemented using an AOP concept, i.e. controller advices with exception handlers are being scanned and cached when wiring the application, then later applied as a cross-cutting concern where necessary for exception handling.
that is to say, spring will create a cut point inside, which matches all @Controller or @RestController modified method, and the aspect is
@Around
or@AfterThrowing
?
Not really. If you look at your controller beans, you will not see any registered AOP advisors on them. If they are not targeted by any other Spring AOP aspects, no dynamic proxies will be created for them either, even if they are targeted by controller advice exception handlers. This is all wired into Spring internally. Probably it could have been implemented using real AOP aspects, similar to how it is done for @Transactional
, but there might be reasons other than just historical ones to hard-wire it, possibly because exception handling is considered a fundamental (low-level?) thing that should be built into the framework.