http请求从tomcat到springmvc的完整流程

在上一篇了解了springMVC是如何被tomcat加载并且整合spring之后,这次来研究一下一个请求是如何传递到我们的controller的.既然要研究请求流程,那么这次从不同的角度来重新看一下 DispatcherServlet . 先来看一下继承图 image.png 我们知道一个请求到达tomcat之后会调用 servlet的service方法我们顺着继承类图开始追踪.

tomcat收到请求

为了能更彻底的了解整个原理,我们从tomcat接受到请求开始追踪整个流程

  1. tomcat监听8080端口.首先是在NioEndPoint中的initServerSocket初始化服务端的监听socket

image.png 2. 收到客户端跟服务端建立连接. tomcat启动了一个 Acceptor线程监听serversocket,如果有客户端连接就把他丢到 selectorimage.png 3. poller线程非阻塞监听selector,看客户端有没有发请求 image.png 4. 真正处理业务的是一个worker线程 image.png

流程图

image.png tomcat的一些细节可以直接看我之前写的tomcat源码分析,里面比较详细

DispatcherServlet 执行流程

我们首先来看一下dispatcherServlet的方法继承 image.png doService方法中其实就是存了一些数据到request域中,然后调用了doDispatch方法 image.png

9大组件

在了解流程之前先看一下SpringMVC的几个重要的组件

  1. MultipartResolver 文件上传处理器
  2. LocalResolver 国际化解析器
  3. ThemeResolver 主题解析器
  4. HandlerMapping 处理器映射: 保存就是所有请求和controller的映射
  5. HandlerAdapter 处理器的适配器
  6. HandlerExceptionResolver handler的异常解析器
  7. RequestToViewNameTranslator 请求转换为视图的翻译器
  8. FlashMapManager 闪存管理器
  9. ViewResolver 视图解析器

这几大组件在initStrategies方法中进行初始化

image.png

在初始化的过程中,只有MultipartResolver文件上传处理器没有默认实现,其他的SpringMVC都会给默认实现 image.png 默认实现的逻辑都差不多,获取一个策略类

image.png 策略类的生成其实就是去DispatcherServlet的类路径下寻找DispatcherServlet.properties文件 image.png 配置文件中配置了不同的策略类

image.png

doDispatch

了解了SpringMVC的组件之后我们正式来看流程

image.png

检查文件上传

image.png

getHandler

获得一个handler,handler我们在配置文件中已经看到了Handler默认有三个实现 image.png 其中最常用的HandlerMapping是RequestMappingHandlerMapping,是用@RequestMapping注解作为url路径映射的。 而另一个RouterFunctionMapping是支持函数式webflux编程的处理器

image.png 我们可以看到在RequestMappingHandlerMapping 中已经保存了请求和处理器的映射,那么我们就来看看这个映射是如何被保存进去的

SpringMVC保存请求和controller映射流程

RequestMappingHandlerMapping实现了spring的生命周期函数,在初始化结束之后会调用钩子方法

image.png 遍历每个bean然后去看有没有注解

image.png 如果有注解的话就会继续执行 image.png 我们先来看遍历controller的方法 image.png 方法就是遍历controller中的每一个方法,然后判断是否有结果,有就加到map里面返回,判断逻辑交给外部实现 image.png 获得完controller的方法之后就是遍历方法注册进去即可 image.png

getHandlerAdapter 获得handler的适配器

我们在上面已经知道了handler的注册和获取逻辑,那么只要反射调用这个handler就可以了,为什么要一个adapter呢,我们来看SpringMVC做了什么 image.png 获得适配器的逻辑很简单,遍历适配器,哪个是适配器可以适配这个handler就返回哪个适配器。适配器也定义在properties中

image.png 随后调用拦截器链,如果有一个返回false则方法就不真正执行 image.png 执行每一个preHandle方法 image.png

TODO 执行目标方法

在获得了适配器之后正式开始执行目标方法,我们先来总览方法

猜你喜欢

转载自juejin.im/post/7110415265271119880