概述
Spring MVC的缺省配置类WebMvcConfigurationSupport定义了一组HandlerExceptionResolver组件到容器,供Spring MVC运行时使用,具体来讲,是被DispatcherServlet使用。本文介绍WebMvcConfigurationSupport定义了哪些HandlerExceptionResolver组件,都是什么类型,以及它们的应用目的。
HandlerExceptionResolver组件定义
WebMvcConfigurationSupport的bean定义方法HandlerExceptionResolver handlerExceptionResolver() 用于定义DispatcherServlet最终使用的一组HandlerExceptionResolver。该bean实际类型是HandlerExceptionResolverComposite,表示多个HandlerExceptionResolver的组合:
/**
* Returns a {@link HandlerExceptionResolverComposite} containing a list of exception
* resolvers obtained either through {@link #configureHandlerExceptionResolvers} or
* through {@link #addDefaultHandlerExceptionResolvers}.
* <p><strong>Note:</strong> This method cannot be made final due to CGLIB constraints.
* Rather than overriding it, consider overriding {@link #configureHandlerExceptionResolvers}
* which allows for providing a list of resolvers.
*/
@Bean
public HandlerExceptionResolver handlerExceptionResolver() {
List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();
configureHandlerExceptionResolvers(exceptionResolvers);
if (exceptionResolvers.isEmpty()) {
addDefaultHandlerExceptionResolvers(exceptionResolvers);
}
extendHandlerExceptionResolvers(exceptionResolvers);
HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
composite.setOrder(0);
composite.setExceptionResolvers(exceptionResolvers);
return composite;
}
bean定义方法HandlerExceptionResolver handlerExceptionResolver() 的工作流程基本如下 :
- 创建空的
List<HandlerExceptionResolver> exceptionResolvers; - 让实现子类指定自己的
HandlerExceptionResolver到exceptionResolvers;
void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers)
- 如果实现子类没指定自己的
HandlerExceptionResolver,则添加缺省的HandlerExceptionResolver到exceptionResolvers;
final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers)
- 让实现子类增加更多自定义的
HandlerExceptionResolver到exceptionResolvers,或者修改exceptionResolvers内容;
void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers)
- 将所有
List<HandlerExceptionResolver> exceptionResolvers包装成一个HandlerExceptionResolverComposite。
缺省情况下,开发人员并不定制和修改exceptionResolvers,换句话讲,此时exceptionResolvers中只有以上第三步WebMvcConfigurationSupport缺省定义的HandlerExceptionResolver被放到exceptionResolvers中。
下面我们重点分析一下这个方法。
final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers)
1. addDefaultHandlerExceptionResolvers
protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
// 定义一个 ExceptionHandlerExceptionResolver
ExceptionHandlerExceptionResolver exceptionHandlerResolver = createExceptionHandlerExceptionResolver();
exceptionHandlerResolver.setContentNegotiationManager(mvcContentNegotiationManager());
exceptionHandlerResolver.setMessageConverters(getMessageConverters());
exceptionHandlerResolver.setCustomArgumentResolvers(getArgumentResolvers());
exceptionHandlerResolver.setCustomReturnValueHandlers(getReturnValueHandlers());
if (jackson2Present) {
exceptionHandlerResolver.setResponseBodyAdvice(
Collections.singletonList(new JsonViewResponseBodyAdvice()));
}
if (this.applicationContext != null) {
exceptionHandlerResolver.setApplicationContext(this.applicationContext);
}
exceptionHandlerResolver.afterPropertiesSet();
exceptionResolvers.add(exceptionHandlerResolver);
// 定义一个 ResponseStatusExceptionResolver
ResponseStatusExceptionResolver responseStatusResolver = new ResponseStatusExceptionResolver();
responseStatusResolver.setMessageSource(this.applicationContext);
exceptionResolvers.add(responseStatusResolver);
// 定义一个 DefaultHandlerExceptionResolver
exceptionResolvers.add(new DefaultHandlerExceptionResolver());
}
从该方法的实现可以看出,Spring MVC缺省使用了三个HandlerExceptionResolver,实现类如下 :
ExceptionHandlerExceptionResolverResponseStatusExceptionResolverDefaultHandlerExceptionResolver
2. 涉及到的HandlerExceptionResolver实现类
1.ExceptionHandlerExceptionResolver
如果某个HanlderMethod执行时发生了异常,尝试找到一个使用了@ExceptionHandler注解的异常处理器将异常转换成ModelAndView的形式,通常对应到一个错误视图error view。
2.ResponseStatusExceptionResolver
尝试使用异常上的@ResponseStatus注解信息将异常翻译成HTTP状态字。
3.DefaultHandlerExceptionResolver
Spring MVC缺省异常处理器,最低优先级,将标准Spring MVC异常翻译成HTTP状态字。
这些类和所实现的接口HandlerExceptionResolver之间的关系如下图所示 :

本文深入解析SpringMVC框架中异常处理的核心组件HandlerExceptionResolver,包括其默认配置的三种实现:ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver,阐述它们如何协同工作以处理控制器抛出的异常。
6146

被折叠的 条评论
为什么被折叠?



