在上一篇了解了springMVC是如何被tomcat加载并且整合spring之后,这次来研究一下一个请求是如何传递到我们的controller的.既然要研究请求流程,那么这次从不同的角度来重新看一下 DispatcherServlet
. 先来看一下继承图 我们知道一个请求到达tomcat之后会调用 servlet的service方法我们顺着继承类图开始追踪.
tomcat收到请求
为了能更彻底的了解整个原理,我们从tomcat接受到请求开始追踪整个流程
- tomcat监听8080端口.首先是在NioEndPoint中的initServerSocket初始化服务端的监听socket
2. 收到客户端跟服务端建立连接. tomcat启动了一个
Acceptor
线程监听serversocket,如果有客户端连接就把他丢到 selector
中 3.
poller
线程非阻塞监听selector,看客户端有没有发请求 4. 真正处理业务的是一个
worker
线程
流程图
tomcat的一些细节可以直接看我之前写的tomcat源码分析,里面比较详细
DispatcherServlet 执行流程
我们首先来看一下dispatcherServlet的方法继承 doService方法中其实就是存了一些数据到request域中,然后调用了doDispatch方法
9大组件
在了解流程之前先看一下SpringMVC的几个重要的组件
- MultipartResolver 文件上传处理器
- LocalResolver 国际化解析器
- ThemeResolver 主题解析器
- HandlerMapping 处理器映射: 保存就是所有请求和controller的映射
- HandlerAdapter 处理器的适配器
- HandlerExceptionResolver handler的异常解析器
- RequestToViewNameTranslator 请求转换为视图的翻译器
- FlashMapManager 闪存管理器
- ViewResolver 视图解析器
这几大组件在initStrategies
方法中进行初始化
在初始化的过程中,只有MultipartResolver文件上传处理器没有默认实现,其他的SpringMVC都会给默认实现 默认实现的逻辑都差不多,获取一个策略类
策略类的生成其实就是去DispatcherServlet的类路径下寻找DispatcherServlet.properties文件
配置文件中配置了不同的策略类
doDispatch
了解了SpringMVC的组件之后我们正式来看流程
检查文件上传
getHandler
获得一个handler,handler我们在配置文件中已经看到了Handler默认有三个实现 其中最常用的HandlerMapping是
RequestMappingHandlerMapping
,是用@RequestMapping注解作为url路径映射的。 而另一个RouterFunctionMapping
是支持函数式webflux编程的处理器
我们可以看到在RequestMappingHandlerMapping 中已经保存了请求和处理器的映射,那么我们就来看看这个映射是如何被保存进去的
SpringMVC保存请求和controller映射流程
RequestMappingHandlerMapping实现了spring的生命周期函数,在初始化结束之后会调用钩子方法
遍历每个bean然后去看有没有注解
如果有注解的话就会继续执行
我们先来看遍历controller的方法
方法就是遍历controller中的每一个方法,然后判断是否有结果,有就加到map里面返回,判断逻辑交给外部实现
获得完controller的方法之后就是遍历方法注册进去即可
getHandlerAdapter 获得handler的适配器
我们在上面已经知道了handler的注册和获取逻辑,那么只要反射调用这个handler就可以了,为什么要一个adapter呢,我们来看SpringMVC做了什么 获得适配器的逻辑很简单,遍历适配器,哪个是适配器可以适配这个handler就返回哪个适配器。适配器也定义在properties中
随后调用拦截器链,如果有一个返回false则方法就不真正执行
执行每一个preHandle方法
TODO 执行目标方法
在获得了适配器之后正式开始执行目标方法,我们先来总览方法