首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca…
一 . 前言
这一篇只关注一个小点 , 学习一下 SpringMVC 是如何进行异常拦截和处理的
二 . 使用
以最基础的 Exception 拦截的使用为例 , 常见的使用方式为 :
1 | java复制代码@ExceptionHandler(Exception.class) |
当在请求中触发了异常之后 , 就会被该通用拦截器拦截到 , 最终给前端抛出 500 异常 .
那么整个流程里面 , 代码层面是怎么处理的呢 ?
三 . 源码梳理
3.1 拦截的入口
方法是在 DispatcherServlet # doDispatch 中进行核心的处理 , 当方法中出现异常了 , 自然也能在其中被 catch 处理掉 , 其主要流程为 :
- Step 1 : 调用方法执行
- Step 2 : 抛出异常后被 catch 捕获 , 记录该异常 , 并不往更外层抛出
- Step 3 : processDispatchResult 中如果发现存在异常 , 则进行异常的处理
doDispatch
1 | java复制代码protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { |
processDispatchResult
1 | java复制代码private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, |
3.2 异常的处理主流程
当异常被捕获到 , 并且通过 processHandlerException 发起异常处理流程后 , 会通过如下流程开始依次处理异常 :
- DispatcherServlet # processHandlerException : 处理起点
- HandlerExceptionResolverComposite # resolveException
- AbstractHandlerExceptionResolver # resolveException
- AbstractHandlerMethodExceptionResolver # doResolveException
- ExceptionHandlerExceptionResolver # doResolveHandlerMethodException
- ServletInvocableHandlerMethod # invokeAndHandle : 调用具体方法
- 调用最后的 @ExceptionHandler 处理方法处理异常
1 | java复制代码protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, |
循环 Exception resolve 列表
1 | java复制代码public ModelAndView resolveException( |
注意 , 这里调用的 resolveException 均为父类 AbstractHandlerExceptionResolver , 由父类再调用子类 doResolveException .
调用 Method 处理方法
1 | java复制代码protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, |
获取实际
1 | java复制代码protected ServletInvocableHandlerMethod getExceptionHandlerMethod( |
四 . 补充 : @ExceptionHandler 的扫描和加载
这一部分来看一下 , @ExceptionHandler 是如何被扫描到容器中的.
1 | java复制代码// 在 ExceptionHandlerExceptionResolver 中存在2个Map 用于存放对应的关联关系 |
4.1 扫描和注入
1 | java复制代码// C- ExceptionHandlerExceptionResolver |
总结
时间有限 , 整体来说还是过一下流程 ,方便后续的问题排查
本文转载自: 掘金