阿里四面之Spring Exception的原理解析

 更新时间:2021年10月25日 10:28:28   作者:JavaEdge.  
本文给大家介绍阿里四面之Spring Exception的原理解析,本文通过错误场景分析给大家详细介绍Spring异常处理流程,感兴趣的朋友一起看看吧

错误场景

验证请求的Token合法性的Filter。Token校验失败时,直接抛自定义异常,移交给Spring处理:

测试HTTP请求:

日志输出如下:说明IllegalRequestExceptionHandler未生效。

why?这就需要精通Spring异常处理流程了。

解析

当所有Filter被执行完毕,Spring才会处理Servlet相关,而DispatcherServlet才是整个Servlet处理核心,它是前端控制器设计模式,提供 Spring Web MVC 的集中访问点并负责职责的分派。

在这,Spring处理了请求和处理器的对应关系及统一异常处理

Filter内异常无法被统一处理,就是因为异常处理发生在 DispatcherServlet#doDispatch()

但此时,过滤器已全部执行完

Spring异常统一处理 ControllerAdvice如何被Spring加载并对外暴露? WebMvcConfigurationSupport#handlerExceptionResolver()

实例化并注册一个ExceptionHandlerExceptionResolver 的实例

最终按下图调用栈,Spring 实例化了ExceptionHandlerExceptionResolver类。

ExceptionHandlerExceptionResolver实现了InitializingBean

 

重写 afterPropertiesSet()

initExceptionHandlerAdviceCache

完成所有 ControllerAdvice 中的ExceptionHandler 初始化:查找所有 @ControllerAdvice 注解的 Bean,把它们放入exceptionHandlerAdviceCache。这里即指自定义的IllegalRequestExceptionHandler

所有被 @ControllerAdvice 注解的异常处理器,都会在 ExceptionHandlerExceptionResolver 实例化时自动扫描并装载在其exceptionHandlerAdviceCache。

initHandlerExceptionResolvers

当第一次请求发生时,DispatcherServlet#initHandlerExceptionResolvers() 将获取所有注册到 Spring 的 HandlerExceptionResolver 实例(ExceptionHandlerExceptionResolver正是),存到handlerExceptionResolvers

ControllerAdvice如何被Spring消费并处理异常? DispatcherServlet doDispatch()

执行用户请求时,当查找、执行请求对应的 handler 过程中异常时:

会把异常值赋给 dispatchException再移交 processDispatchResult() processDispatchResult

当Exception非空时,继续移交

processHandlerException

从 handlerExceptionResolvers 获取有效的异常解析器以解析异常。

这里的 handlerExceptionResolvers 一定包含声明的IllegalRequestExceptionHandler#IllegalRequestException 的异常处理器的 ExceptionHandlerExceptionResolver 包装类。

修正

为利用到 Spring MVC 的异常处理机制,改造Filter:

手动捕获异常将异常通过 HandlerExceptionResolver 进行解析处理

据此,修改 PermissionFilter,注入 HandlerExceptionResolver:

然后,在 doFilter 捕获异常并移交 HandlerExceptionResolver:

现在再用错误 Token 请求,日志输出如下:

响应体:

到此这篇关于阿里四面之Spring Exception的原理解析的文章就介绍到这了,更多相关Spring Exception原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis使用@mapkey获取的结果的键(key)为null问题

    mybatis使用@mapkey获取的结果的键(key)为null问题

    这篇文章主要介绍了mybatis使用@mapkey获取的结果的键(key)为null问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • 图文详解Java中的序列化机制

    图文详解Java中的序列化机制

    java中的序列化可能大家像我一样都停留在实现Serializable接口上,对于它里面的一些核心机制没有深入了解过。本文将通过示例带大家深入了解Java中的序列化机制,需要的可以参考一下
    2022-10-10
  • java获取中文拼音首字母工具类定义与用法实例

    java获取中文拼音首字母工具类定义与用法实例

    这篇文章主要介绍了java获取中文拼音首字母工具类定义与用法,结合实例形式分析了java获取中文拼音首字母工具类的具体定义、使用方法及相关操作注意事项,需要的朋友可以参考下
    2019-10-10
  • WIN7系统JavaEE(tomcat7 Eclipse)环境配置教程(二)

    WIN7系统JavaEE(tomcat7 Eclipse)环境配置教程(二)

    这篇文章主要介绍了WIN7系统JavaEE(java+tomcat7+Eclipse)环境配置教程,本文重点在于tomcat配置、Eclipse配置,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • 如何基于http代理解决Java固定ip问题

    如何基于http代理解决Java固定ip问题

    这篇文章主要介绍了如何基于http代理解决Java固定ip问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • java对象对比之comparable和comparator的区别

    java对象对比之comparable和comparator的区别

    今天给大家带来的是关于Java的相关知识,文章围绕着comparable和comparator的区别展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • Java命名规则详细总结

    Java命名规则详细总结

    Class名应是首字母大写的名词。命名时应该使其简洁而又具有描述性。异常类的命名,应以Exception结尾。Interface的命名规则与Class相同
    2013-10-10
  • springboot整合quartz定时任务框架的完整步骤

    springboot整合quartz定时任务框架的完整步骤

    在做项目时有时候会有定时器任务的功能,比如某某时间应该做什么,多少秒应该怎么样之类的,下面这篇文章主要给大家介绍了关于springboot整合quartz定时任务框架的相关资料,需要的朋友可以参考下
    2022-01-01
  • Zookeeper中如何解决zookeeper.out文件输出位置问题

    Zookeeper中如何解决zookeeper.out文件输出位置问题

    这篇文章主要介绍了Zookeeper中如何解决zookeeper.out文件输出位置问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • Java通过MyBatis框架对MySQL数据进行增删查改的基本方法

    Java通过MyBatis框架对MySQL数据进行增删查改的基本方法

    MyBatis框架由Java的JDBC API进一步封装而来,在操作数据库方面效果拔群,接下来我们就一起来看看Java通过MyBatis框架对MySQL数据进行增删查改的基本方法:
    2016-06-06

最新评论