springmvc源码解析(2)--请求处理流程概览

打断点分析

分析任何源码时,如果一开始不清楚类的继承结构,具体执行流程,都可以通过打断点的方式获得调用栈,然后就知道具体如何执行。
在这里插入图片描述
在上面打断点后,具体调用栈如下

test:51, DemoController (com.lagou.edu.controller)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
doInvoke:190, InvocableHandlerMethod (org.springframework.web.method.support)
invokeForRequest:138, InvocableHandlerMethod (org.springframework.web.method.support)
invokeAndHandle:105, ServletInvocableHandlerMethod (org.springframework.web.servlet.mvc.method.annotation)
invokeHandlerMethod:893, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handleInternal:798, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handle:87, AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)
doDispatch:1040, DispatcherServlet (org.springframework.web.servlet)
doService:943, DispatcherServlet (org.springframework.web.servlet)
processRequest:1006, FrameworkServlet (org.springframework.web.servlet)
doGet:898, FrameworkServlet (org.springframework.web.servlet)
service:621, HttpServlet (javax.servlet.http)
service:883, FrameworkServlet (org.springframework.web.servlet)
service:728, HttpServlet (javax.servlet.http)
internalDoFilter:305, ApplicationFilterChain (org.apache.catalina.core)
doFilter:210, ApplicationFilterChain (org.apache.catalina.core)
doFilter:51, WsFilter (org.apache.tomcat.websocket.server)
internalDoFilter:243, ApplicationFilterChain (org.apache.catalina.core)
doFilter:210, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:201, CharacterEncodingFilter (org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:243, ApplicationFilterChain (org.apache.catalina.core)
doFilter:210, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:94, HiddenHttpMethodFilter (org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:243, ApplicationFilterChain (org.apache.catalina.core)
doFilter:210, ApplicationFilterChain (org.apache.catalina.core)
invoke:222, StandardWrapperValve (org.apache.catalina.core)
invoke:123, StandardContextValve (org.apache.catalina.core)
invoke:502, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:171, StandardHostValve (org.apache.catalina.core)
invoke:100, ErrorReportValve (org.apache.catalina.valves)
invoke:953, AccessLogValve (org.apache.catalina.valves)
invoke:118, StandardEngineValve (org.apache.catalina.core)
service:408, CoyoteAdapter (org.apache.catalina.connector)
process:1041, AbstractHttp11Processor (org.apache.coyote.http11)
process:603, AbstractProtocol$AbstractConnectionHandler (org.apache.coyote)
run:312, JIoEndpoint$SocketProcessor (org.apache.tomcat.util.net)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:745, Thread (java.lang)

从上面的调用栈可以分析得知一个关键点,就是从HttpServlet.service方法开始执行(更下面的细节可以忽略)
最终调用DispatcherServlet.doDispatch开始真正的请求转发,大概执行流程就是如下

  1. HttpServlet.service
  2. FrameworkServlet.service
  3. HttpServlet.service
  4. FrameworkServlet.doGet
  5. FrameworkServlet.processRequest
  6. DispatcherServlet.doService
  7. DispatcherServlet.doDispatch
  • 下面开始分析具体流程

HttpServlet.service

主要功能是根据不同的请求方式,调用不同的分支方法,不负责具体逻辑
在这里插入图片描述

FrameworkServlet.service

该方法重写了父类的service方法,单独用于处理HttpMethod.PATCH分支,其他情况调用父类的service方法
在这里插入图片描述
从上面就可以看出之前的调用栈为什么是HttpServlet.service - -> FrameworkServlet.service --> HttpServlet.service
因为FrameworkServlet虽然你实现HttpServlet的service方法,但是只处理了HttpMethod.PATCH这种请求方式,其他的依然由父类实现

FrameworkServlet.doGet

  1. 没有业务逻辑,直接调用内部的processRequest方法
  2. 此类的doGet doPost doPut doDelete doOptions 等等方法都是调用processRequest
    在这里插入图片描述

FrameworkServlet.processRequest

  1. 获取上一个请求保存的LocaleContext
  2. 建立新的LocaleContext
  3. 获取上一个请求保存的RequestAttributes
  4. 建立新的RequestAttributes
  5. 新的RequestAttributes设置进LocalThread
  6. 调用doService处理请求,此类中是个抽象方法,由子类DispatcherServlet实现
    在这里插入图片描述

DispatcherServlet.doService

主要负责设置request的相关属性,真正的请求转发由doDispatch实现
在这里插入图片描述

DispatcherServlet.doDispatch

这个才是最终的请求转发处理流程,主要流程有以下几个方面

  1. 文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析
  2. 通过HandlerMapping,获取请求映射到处理器HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器,处理请求时,先经过拦截器链处理完成后,才通过Handler处理请求
  3. 根据Handler获取处理请求的处理器适配器 HandlerAdapter,因为不同的请求处理方式可能不一样,通过适配器封装成统一的处理方式
  4. applyPreHandle 调用HandlerExecutionChain的interceptor 执行请求前置处理
  5. 实际处理器处理请求,返回结果视图对象
  6. applyPostHandle调用HandlerExecutionChain的interceptor 执行请求后置处理
  7. 最终调用HandlerInterceptor的afterCompletion 方法
    在这里插入图片描述在这里插入图片描述

总结

以上就是请求的大概处理流程,大致流程如下,每一个分支流程的细节会在后面的文章详细分析。

  1. 如果是文件上传请求,处理文件上传
  2. 先根据url获取请求处理器,
  3. 获取处理器适配,
  4. 真正的处理请求并返回结果视图,
  5. 在处理请求的前后有拦截器的前置和后置处理,
  6. 最后调用拦截器的afterCompletion方法,不管有没有异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值