SpringBoot一个请求的处理全过程分享

 更新时间:2024年12月14日 08:54:17   作者:骑个小蜗牛  
本文详细介绍了SpringBoot请求处理的全过程,包括过滤器链、拦截器链、路径映射、参数绑定、Controller方法执行、返回值处理、异常解析和视图解析渲染等步骤,同时,文中还列举了请求处理过程中常见的问题及解决方案

平时只是在用SpringBoot框架,但并没有详细研究过请求执行的一个具体过程,所以本文主要来梳理一下SpringBoot请求处理的全过程。

请求处理流程图

容器包含关系图

请求简要流程图

请求详细流程图

请求处理流程详解

请求处理主要流程

  1. 过滤器链chain.doFilter之前的执行(过滤器是在Server容器中的,如Tomcat);
  2. 拦截器链preHandle方法执行;
  3. 路径映射、参数绑定(参数解析、参数转换、参数校验);
  4. Controller的具体方法执行;
  5. 返回值处理(含信息转换);
  6. 拦截器链postHandle方法执行;
  7. 异常解析器处理异常(@ControllerAdvice、自定义异常解析器都在这里执行);
  8. 视图解析渲染;
  9. 拦截器链afterCompletion方法执行;
  10. 过滤器链chain.doFilter之后的执行。

请求处理详细流程

Tomcat线程接受到请求,经过一系列调用后,调用到ApplicationFilterChain的doFilter方法。doFilter方法调用ApplicationFilterChain的internalDoFilter方法,依次执行过滤器链的每个Filter的doFilter。

过滤器链的所有doFIlter执行完毕, 控制权交回ApplicationFilterChain, 经过一系列调用后,调用到DispatcherServlet的doDispatch方法。

doDispatch方法的主要流程:

  • DispatcherServlet的getHandler方法:得到处理执行器链(包含处理器和拦截器链)。
  • DispatcherServlet的getHandlerAdapter方法:得到处理器适配器。
  • HandlerExecutionChain的applyPreHandle方法:执行执行器链中的所有拦截器方法preHandle。

AbstractHandlerMethodAdapter的handle方法:该方法主要包含路径映射、参数bangd (参数解析、参数转换、参数校验)、调用具体控制器方法、返回值处理(含信息转换)等操作。

handle方法的主要流程:

  • 调用RequestMappingHandlerAdapter的handleInternal方法
  • handleInternal方法又调用RequestMappingHandlerAdapter的invokeHandlerMethod方法

invokeHandlerMethod方法的主要流程:

  • 调用RequestMappingHandlerAdapter的createInvocableHandlerMethod方法:注册参数解析器、返回值处理器、信息转化器等到ServletInvocableHandlerMethod 对象实例中。
  • 调用ServletInvocableHandlerMethod的invokeAndHandle方法。

invokeAndHandle方法的主要流程:

  • 调用InvocableHandlerMethod的invokeForRequest方法
  • invokeForRequest方法又调用InvocableHandlerMethod的doInvoke方法

doInvoke方法的主要流程:

  • 调用InvocableHandlerMethod的getMethodArgumentValues方法:路径映射、参数绑定(参数解析、参数转换、参数校验)。
  • 调用Method的invoke方法,内部调用DelegatingMethodAccessorImpl的invoke方法,内部调用InvocableHandlerMethod的doInvoke方法,内部调用NativeMethodAccessorImpl的invoke方法,内部调用NativeMethodAccessorImpl的invoke0方法,内部调用具体Controller的具体方法,得到响应结果。
  • 调用HandlerMethodReturnValueHandlerComposite的handleReturnValue方法:返回值处理(含信息转换)。
  • 调用HandlerExecutionChain的applyPostHandle方法:执行执行器链中的所有拦截方法postHandle。
  • 调用DispatcherServlet的processDispatchResult方法。

processDispatchResult方法的主要流程:

  • 调用DispatcherServlet的processHandlerException方法:异常处理(获取合适的异常解析器处理异常信息,@ControllerAdvice全局异常处理和自定义异常解析器都是在这一步执行的)。
  • 调用DispatcherServlet的render方法:视图解析渲染。
  • 调用HandlerExecutionChain的triggerAfterCompletion方法:执行执行器链中的所有拦截方法afterCompletion。
  • 控制权交回ApplicationFilterChain , 继续执行过滤器链的所有doFIlter之后的代码。

常见问题

全局异常处理失效

1.@ControllerAdvice作用范围

拦截器的preHandle方法、postHandle方法抛出的异常在ControllerAdvice处理范围内,但拦截器的afterCompletion方法抛出的异常不在处理范围内(拦截器的afterCompletion抛出的异常会被直接catch处理,不会往外抛出异常,只会打印错误日志)。

HandlerExecutionChain类源码

void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
			throws Exception {

		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = this.interceptorIndex; i >= 0; i--) {
				HandlerInterceptor interceptor = interceptors[i];
				try {
					interceptor.afterCompletion(request, response, this.handler, ex);
				}
				catch (Throwable ex2) {
					logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
				}
			}
		}
	}

过滤器抛出的异常不在ControllerAdvice处理范围内。要处理过滤器抛出的异常,可以自定义Filter并放在过滤链的最前面,catch处理异常。

2.多个@ControllerAdvice优先级问题

  • 多个使用@ControllerAdvice 的Bean按执行顺序(通过Order注解设置执行顺序,值越小月优先执行)依次执行
  • 当某个Bean的方法匹配上异常时,进行异常处理,直接返回,后续的方法和Bean不在执行。

关于全局异常处理详细讲解可参考文章:[SpringBoot全局异常处理]

后续文章会继续针对请求流程里面的一些主要功能作深入探讨,如:过滤器拦截器参数解析参数转换参数校验返回值处理异常处理等方面

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解eclipse项目中的.classpath文件原理

    详解eclipse项目中的.classpath文件原理

    这篇文章介绍了eclipse项目中的.classpath文件的原理,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • 作为Java程序员应该掌握的10项技能

    作为Java程序员应该掌握的10项技能

    这篇文章主要介绍了作为Java程序员应该掌握的10项技能,包括java的知识点与相关的技能,对于java的学习有不错的参考借鉴价值,需要的朋友可以参考下
    2015-05-05
  • JSONArray在Java中的应用操作实例

    JSONArray在Java中的应用操作实例

    JSONArray是org.json库用于处理JSON数组的类,可将Java对象(Map/List)转换为JSON格式,提供增删改查等操作,适用于前后端数据交互,并涵盖安全、性能优化及最佳实践,本文给大家介绍JSONArray在Java中的应用,感兴趣的朋友一起看看吧
    2025-07-07
  • 从0开始学习大数据之java spark编程入门与项目实践

    从0开始学习大数据之java spark编程入门与项目实践

    这篇文章主要介绍了从0开始学习大数据之java spark编程入门与项目实践,结合具体入门项目分析了大数据java spark编程项目建立、调试、输出等相关步骤及操作技巧,需要的朋友可以参考下
    2019-11-11
  • Spring MVC数据绑定方式

    Spring MVC数据绑定方式

    这篇文章主要介绍了Spring MVC数据绑定方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Spring Boot 整合 SSE(Server-Sent Events)实战案例(全网最全)

    Spring Boot 整合 SSE(Server-Sent Events)实战案例(全网最全)

    本文通过实战案例讲解SpringBoot整合SSE技术,涵盖实现原理、代码配置、异常处理及前端交互,讨论与WebSocket对比、分布式解决方案、性能监控,感兴趣的朋友跟随小编一起看看吧
    2025-08-08
  • SpringBoot 单元测试实战(Mockito,MockBean)

    SpringBoot 单元测试实战(Mockito,MockBean)

    这篇文章主要介绍了SpringBoot 单元测试实战(Mockito,MockBean),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Spring Security组件一键接入验证码登录和小程序登录的详细过程

    Spring Security组件一键接入验证码登录和小程序登录的详细过程

    这篇文章主要介绍了Spring Security 一键接入验证码登录和小程序登录,简单介绍一下这个插件包的相关知识,本文结合示例代码给大家介绍的非常详细,需要的朋友参考下吧
    2022-04-04
  • Spring Boot实现MyBatis动态创建表的操作语句

    Spring Boot实现MyBatis动态创建表的操作语句

    这篇文章主要介绍了Spring Boot实现MyBatis动态创建表,MyBatis提供了动态SQL,我们可以通过动态SQL,传入表名等信息然组装成建表和操作语句,本文通过案例讲解展示我们的设计思路,需要的朋友可以参考下
    2024-01-01
  • Java基于线程实现带有滚动效果的Label标签实例

    Java基于线程实现带有滚动效果的Label标签实例

    这篇文章主要介绍了Java基于线程实现带有滚动效果的Label标签,实例分析了java线程的使用技巧及label标签的实现方法,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07

最新评论