【AOP】@RestControllerAdvice源码

21 阅读1分钟

一、异常处理对象初始化

// ExceptionHandlerExceptionResolver(异常处理对象管理)
// ExceptionHandlerMethodResolver   (异常处理方法管理)
ExceptionHandlerExceptionResolver:
private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache = new LinkedHashMap()
initExceptionHandlerAdviceCache()
List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(this.getApplicationContext())
Class<?> beanType = adviceBean.getBeanType()
ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType)
this.exceptionHandlerAdviceCache.put(adviceBean, resolver)

ExceptionHandlerMethodResolver:
public ExceptionHandlerMethodResolver(Class<?> handlerType)
for (Method method : MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {
	for (Class<? extends Throwable> exceptionType : detectExceptionMappings(method)) {
	addExceptionMapping(exceptionType, method);
	}
}
Method oldMethod = this.mappedMethods.put(exceptionType, method)

二、异常捕获

DispatcherServlet:
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException)
exMv = resolver.resolveException(request, response, handler, ex)

三、异常处理匹配

ExceptionHandlerExceptionResolver:
ServletInvocableHandlerMethod exceptionHandlerMethod = this.getExceptionHandlerMethod(handlerMethod, exception)
Iterator var9 = this.exceptionHandlerAdviceCache.entrySet().iterator()
Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry = (Entry)var9.next()
ControllerAdviceBean advice = (ControllerAdviceBean)entry.getKey()
if (advice.isApplicableToBeanType(handlerType))
Method method = resolver.resolveMethod(exception)

ExceptionHandlerMethodResolver:
private Method getMappedMethod(Class<? extends Throwable> exceptionType)
for (Class<? extends Throwable> mappedException : this.mappedMethods.keySet())
if (mappedException.isAssignableFrom(exceptionType))
matches.add(mappedException)
matches.sort(new ExceptionDepthComparator(exceptionType))
return this.mappedMethods.get(matches.get(0))

四、异常处理执行

ExceptionHandlerExceptionResolver:
exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, arguments)

InvocableHandlerMethod:
method.invoke(getBean(), args)