org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver{
public void afterPropertiesSet() {
// 初始化被@ControllerAdvice标注的类,在HandlerAdapter中也做过这件事
initExceptionHandlerAdviceCache();{
List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());{
// 保存添加了@ControllerAdvice注解的类信息
List<ControllerAdviceBean> adviceBeans = new ArrayList<>();
// 找到所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Object.class);
for (String name : beanNames) {
// 判断是否是代理的Bean,添加了@Scoped的标识,添加了返回true
if (!ScopedProxyUtils.isScopedTarget(name)) {
// 找到Bean中带有@ControllerAdvice的类
ControllerAdvice controllerAdvice = beanFactory.findAnnotationOnBean(name, ControllerAdvice.class);
if (controllerAdvice != null) {
// 将这些信息包装成ControllerAdviceBean对象,避免后续再次找相同的Bean
adviceBeans.add(new ControllerAdviceBean(name, beanFactory, controllerAdvice));
}
}
}
// 对这些bean进行排序
OrderComparator.sort(adviceBeans);
return adviceBeans;
}
// 遍历找到的adviceBean
for (ControllerAdviceBean adviceBean : adviceBeans) {
// 获取Bean的类型
Class<?> beanType = adviceBean.getBeanType();
// 创建一个ExceptionHandlerMethodResolver对象,是为了处理标注了@ExceptionHandler的方法
// 因为标注了@ExceptionHandler就有点类似于@RequestMapping
// 一个是异常情况下的执行方法,一个是正常情况下的执行方法
ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);{
// 找到标注了ExceptionHandler的方法
// EXCEPTION_HANDLER_METHODS = method -> AnnotatedElementUtils.hasAnnotation(method, ExceptionHandler.class);
for (Method method : MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {
// detectExceptionMappings: 遍历在方法中的异常参数,例如NullE,Ex,Th等等异常
for (Class<? extends Throwable> exceptionType : detectExceptionMappings(method){
ExceptionHandler ann = AnnotatedElementUtils.findMergedAnnotation(method, ExceptionHandler.class);
result.addAll(Arrays.asList(ann.value()));
// 如果没有在@ExceptionHandler添加异常参数
if (result.isEmpty()) {
// 找到参数中为Throwable的异常对象,保存到result中
// 如果没有,就会抛出异常
for (Class<?> paramType : method.getParameterTypes()) {
if (Throwable.class.isAssignableFrom(paramType)) {
result.add((Class<? extends Throwable>) paramType);
}
}
}
}) {
// 保存异常方法和数据,将异常类型作为Key,Method方法作为value本身
addExceptionMapping(exceptionType, method);{
Method oldMethod = this.mappedMethods.put(exceptionType, method);
// 如果存在两种一样的的Exception的方法,就要报错了
if (oldMethod != null && !oldMethod.equals(method)) {
throw new IllegalStateException("Ambiguous @ExceptionHandler method mapped for");
}
}
}
}
}
// 上面如果保存了异常数据,这里就符合条件mappedMethods有值
if (resolver.hasExceptionMappings(){
return !this.mappedMethods.isEmpty();
}) {
// 保存到当前ExceptionResolver的缓存中exceptionHandlerAdviceCache
this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
}
// 如果当前bean的类型是ResponseBodyAdvice这个类型
if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
// 还要保存到responseBodyAdvice这里
this.responseBodyAdvice.add(adviceBean);
}
}
}
if (this.argumentResolvers == null) {
// 获取处理异常方法的参数解析器
List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();{
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
// 处理@SessionAttribute和@RequestAttribute的参数解析器
resolvers.add(new SessionAttributeMethodArgumentResolver());
resolvers.add(new RequestAttributeMethodArgumentResolver());
// 处理参数为req,resp,model,RedirectAttributes的处理器
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
resolvers.add(new RedirectAttributesMethodArgumentResolver());
resolvers.add(new ModelMethodProcessor());
// 自定义的参数解析器
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// 兜底的参数解析器
resolvers.add(new PrincipalMethodArgumentResolver());
return resolvers;
}
// 将参数解析器包装到HandlerMethodArgumentResolverComposite内
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
// 返回值处理器
if (this.returnValueHandlers == null) {
// 获取默认的返回值处理器
List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers(){
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();
// 处理ModeAndView,Model,View,httpEntity的返回值
handlers.add(new ModelAndViewMethodReturnValueHandler());
handlers.add(new ModelMethodProcessor());
handlers.add(new ViewMethodReturnValueHandler());
handlers.add(new HttpEntityMethodProcessor(
getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));
// 处理返回值为req,resp的
handlers.add(new ServletModelAttributeMethodProcessor(false));
handlers.add(new RequestResponseBodyMethodProcessor(
getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));
// 处理返回值为String的视图
handlers.add(new ViewNameMethodReturnValueHandler());
// 返回Map的处理器
handlers.add(new MapMethodProcessor());
// 自定义的返回值处理器
if (getCustomReturnValueHandlers() != null) {
handlers.addAll(getCustomReturnValueHandlers());
}
// 兜底的返回值处理器
handlers.add(new ServletModelAttributeMethodProcessor(true));
return handlers;
};
// 将参数解析器包装到HandlerMethodReturnValueHandlerComposite内
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}
}