Spring Boot源码之旅四十五SpringMVC源码细节之异常处理一

文章详细介绍了JavaWeb开发中异常处理的原理,包括多线程、源码级解析,如JUC源码、JVM源码,以及Spring框架的异常处理策略,如`HandlerExceptionResolver`的工作原理。特别关注了默认异常解析器对特定异常的处理过程。
摘要由CSDN通过智能技术生成

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

 

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

 

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

基本处理流程图

通常的异常处理

我们来演示下,看看通常异常是怎么处理的,我们什么都不加,只是这样,看看内部怎么处理的:


运行:


运行到这里的时候直接抛异常:


doDispatch方法中会保存异常。


然后处理结果:


走有异常的逻辑:


进行异常解析器解析,DefaultErrorAttributes只是添加了异常属性,什么都没做:


HandlerExceptionResolverComposite是一个异常解析器的符合解析器,里面有解析器处理。

是否能解析异常

ExceptionHandlerExceptionResolver的shouldApplyTo

一般只解析HandlerMethod处理器类型的异常,刚好我们就是这个类型的处理器。


最终到AbstractHandlerExceptionResolvershouldApplyTo,我们没有映射的处理器来处理,所以全部为空的话也是返回true,表示可以处理:

doResolveHandlerMethodException处理

如果没有设置异常处理方法就返回null了,等于没处理,其实这里的方法是可以自定义的,后面说。

ResponseStatusExceptionResolver的处理

这个也是AbstractHandlerExceptionResolvershouldApplyTo,最终也是没处理:

DefaultHandlerExceptionResolver的处理

这个也是AbstractHandlerExceptionResolvershouldApplyTo,但是最后还是没处理,不过他已经判断了很多中异常了:

    @Override
    	@Nullable
    	protected ModelAndView doResolveException(
    			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
    
    		try {
    			if (ex instanceof HttpRequestMethodNotSupportedException) {
    				return handleHttpRequestMethodNotSupported(
    						(HttpRequestMethodNotSupportedException) ex, request, response, handler);
    			}
    			else if (ex instanceof HttpMediaTypeNotSupportedException) {
    				return handleHttpMediaTypeNotSupported(
    						(HttpMediaTypeNotSupportedException) ex, request, response, handler);
    			}
    			else if (ex instanceof HttpMediaTypeNotAcceptableException) {
    				return handleHttpMediaTypeNotAcceptable(
    						(HttpMediaTypeNotAcceptableException) ex, request, response, handler);
    			}
    			else if (ex instanceof MissingPathVariableException) {
    				return handleMissingPathVariable(
    						(MissingPathVariableException) ex, request, response, handler);
    			}
    			else if (ex instanceof MissingServletRequestParameterException) {
    				return handleMissingServletRequestParameter(
    						(MissingServletRequestParameterException) ex, request, response, handler);
    			}
    			else if (ex instanceof ServletRequestBindingException) {
    				return handleServletRequestBindingException(
    						(ServletRequestBindingException) ex, request, response, handler);
    			}
    			else if (ex instanceof ConversionNotSupportedException) {
    				return handleConversionNotSupported(
    						(ConversionNotSupportedException) ex, request, response, handler);
    			}
    			else if (ex instanceof TypeMismatchException) {
    				return handleTypeMismatch(
    						(TypeMismatchException) ex, request, response, handler);
    			}
    			else if (ex instanceof HttpMessageNotReadableException) {
    				return handleHttpMessageNotReadable(
    						(HttpMessageNotReadableException) ex, request, response, handler);
    			}
    			else if (ex instanceof HttpMessageNotWritableException) {
    				return handleHttpMessageNotWritable(
    						(HttpMessageNotWritableException) ex, request, response, handler);
    			}
    			else if (ex instanceof MethodArgumentNotValidException) {
    				return handleMethodArgumentNotValidException(
    						(MethodArgumentNotValidException) ex, request, response, handler);
    			}
    			else if (ex instanceof MissingServletRequestPartException) {
    				return handleMissingServletRequestPartException(
    						(MissingServletRequestPartException) ex, request, response, handler);
    			}
    			else if (ex instanceof BindException) {
    				return handleBindException((BindException) ex, request, response, handler);
    			}
    			else if (ex instanceof NoHandlerFoundException) {
    				return handleNoHandlerFoundException(
    						(NoHandlerFoundException) ex, request, response, handler);
    			}
    			else if (ex instanceof AsyncRequestTimeoutException) {
    				return handleAsyncRequestTimeoutException(
    						(AsyncRequestTimeoutException) ex, request, response, handler);
    			}
    		}
    		catch (Exception handlerEx) {
    			if (logger.isWarnEnabled()) {
    				logger.warn("Failure while trying to resolve exception [" + ex.getClass().getName() + "]", handlerEx);
    			}
    		}
    		return null;
    	}

默认的异常处理都处理不了我这个异常java.lang.ArithmeticException: / by zero,然后就抛到tomcat里去了,我们后面说。

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值