如果未获得到,则获得默认配置的 HandlerExceptionResolver 类,调用 getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) 方法,就是从 DispatcherServlet.properties 文件中读取 HandlerExceptionResolver 的默认实现类,如下:
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\ org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\ org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver在 Spring Boot 中,默认配置下会走上述 1 的逻辑,handlerExceptionResolvers 有两个元素:
org.springframework.boot.autoconfigure.web.DefaultErrorAttributes:在 Spring Boot 中,逻辑比较简单,暂时忽略
org.springframework.web.servlet.handler.HandlerExceptionResolverComposite:复合的 HandlerExceptionResolver 实现类
接下来会对 HandlerExceptionResolverComposite 中的这三种异常处理器进行分析
HandlerExceptionResolverCompositeorg.springframework.web.servlet.handler.HandlerExceptionResolverComposite,实现 HandlerExceptionResolver、Ordered 接口,复合的 HandlerExceptionResolver 实现类
构造方法 public class HandlerExceptionResolverComposite implements HandlerExceptionResolver, Ordered { /** * 异常解析器数组 */ @Nullable private List<HandlerExceptionResolver> resolvers; /** * 优先级,默认最低 */ private int order = Ordered.LOWEST_PRECEDENCE; }resolvers:HandlerExceptionResolver 实现类列表
order:优先级,默认最低
从上面的初始化过程中可以看到,Spring Boot 默认配置下 HandlerExceptionResolverComposite 包含三个实现类:
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
resolveException实现 resolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) 方法,遍历 HandlerExceptionResolver 数组,逐个处理异常 ex,如果成功,则返回 ModelAndView 对象,方法如下:
@Override @Nullable public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) { if (this.resolvers != null) { for (HandlerExceptionResolver handlerExceptionResolver : this.resolvers) { ModelAndView mav = handlerExceptionResolver.resolveException(request, response, handler, ex); if (mav != null) { return mav; } } } return null; } AbstractHandlerExceptionResolverorg.springframework.web.servlet.handler.AbstractHandlerExceptionResolver,实现 HandlerExceptionResolver、Ordered 接口,HandlerExceptionResolver 抽象类,作为所有 HandlerExceptionResolver 实现类的基类
构造方法 public abstract class AbstractHandlerExceptionResolver implements HandlerExceptionResolver, Ordered { private static final String HEADER_CACHE_CONTROL = "Cache-Control"; /** * 优先级,默认最低 */ private int order = Ordered.LOWEST_PRECEDENCE; /** * 匹配的处理器对象的集合 */ @Nullable private Set<?> mappedHandlers; /** * 匹配的处理器类型的数组 */ @Nullable private Class<?>[] mappedHandlerClasses; /** * 防止响应缓存 */ private boolean preventResponseCaching = false; }上面的这些属性在后续方法中会讲到
shouldApplyToshouldApplyTo(HttpServletRequest request, Object handler) 方法,判断当前 HandlerExceptionResolver 是否能应用到传入的 handler 处理器,方法如下:
protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) { if (handler != null) { // <1> 如果 mappedHandlers 包含 handler 对象,则返回 true if (this.mappedHandlers != null && this.mappedHandlers.contains(handler)) { return true; } // <2> 如果 mappedHandlerClasses 包含 handler 的类型,则返回 true if (this.mappedHandlerClasses != null) { for (Class<?> handlerClass : this.mappedHandlerClasses) { if (handlerClass.isInstance(handler)) { return true; } } } } // Else only apply if there are no explicit handler mappings. // <3> 如果 mappedHandlers 和 mappedHandlerClasses 都为空,说明直接匹配 return (this.mappedHandlers == null && this.mappedHandlerClasses == null); }如果 mappedHandlers 包含该 handler 处理器对象,则返回 true
如果 mappedHandlerClasses 包含该 handler 处理器所在类,则返回 true
如果 mappedHandlers 和 mappedHandlerClasses 都为空,说明直接匹配
prepareResponse