上一篇文章介绍了一下SpringMVC的初始化过程,本篇文章我们正式开始进入SpirngMVC的执行流程
先上一个流程图
首先,还是先进入DispatcherServlet中,跳过要加载的组件(如需看加载的组件请看上一篇博客文章尾部)我们直接来到doService()方法
首先对请求的参数进行封装的操作,然后设置一些SpirngMVC的参数进去,之后的执行由doDispatcher(request,response)来执行,可以说SpringMVC的整个执行流程都在doDispatcher()方法中,这也是这篇文章的绝对猪脚
接下来让我们详细解析一下doDispatcher方法体中都干了什么
HandlerExecutionChain : 执行链,是HandlerMapping中返回的
multipartRequestParsed : 是否是文件上传请求
WebAsyncManager : web的异步请求管理器,这个一般只有比较复杂的业务逻辑才会用到,为的是防止线程阻塞,需要将当前操作委托给另一个线程的时候才会用的到的
接下来就是具体的操作了
这部分代码中的checkMultipart(request)方法是监测当前请求是否是文件上传,是的话就对multipartRequestParsed重新赋值
下面代码需要看容器内部的东西,我们需要进入Debug模式
首先是getHandler(request)方法
一个比较简单的方法体,对handlerMappings中的所有映射处理器进行迭代,判断当前请求应该使用哪一个处理器,选取与当前请求适配的处理器返回执行链handler
RequestMappingHandlerMapping : 相信很多人看到这个第一时间应该想的是@RequestMapping()这个标签,没错,就是他
BeanNameUrlHandlerMappint : 这个我们现在开发已经不是很常用了,这个是通过在springmvc.xml文件中配置
WebSocketHandlerMapping : 这个是处理socket连接的
接下来我们进入根据执行链选择适配器阶段
与getHandler()方法中的逻辑基本一致,我们来看看都有什么适配器
SimpleControllerHandlerAdapter : 当你的Controller实现了Controller接口的时候用到的适配器就是它
applyPreHandle()这个方法是在执行执行链之前执行的,用来处理拦截器的,在启动Spring容器的时候,Spirng会将所有的拦截器全部放到一个集合中
HandlerInterceptor : Spring中拦截器的基类,创建拦截器需要实现接口
如果在实际开发中,需要创建这个的实例的话,个人觉得工厂设计模式比较适合,有点跑题哈...
迭代所有的拦截器,并执行preHandle方法,如果你感兴趣你可以打断点到你的拦截器中,看它执行
SignInterceptor这个拦截器是我项目中的拦截器
在handle()方法中,开始执行执行链,并且注入参数,执行对应的业务方法,这里的err就是返回的逻辑视图ModelAndView对象,下面依然又判断了一次当前是否开启了异步操作
业务也执行完毕了,接下来当然是要返回视图了
applyDefaultViewName()这个方法也比较简单,是通过request来获取请求的默认视图
mappedHandler这个家伙有没有感觉好像再哪看到过,是它调用的
applyPreHandle()方法,迭代拦截器并执行preHandle()这个方法,根据这个applyPostHandle()这个方法有没有感觉很眼熟啊
这个方法同样属于HandlerInterceptor这个接口,所以你应该明白了,它调用的就是你的拦截器中的postHandle()的方法
preHandle()是在所有请求之前执行的,这个方法是用于请求之后的处理
接下来,倒数第二步
返回视图,在浏览器上显示
最后一步....
就是finally代码块中的逻辑,multipartRequestParsed相信大家看的也很眼熟,这个是doDispatcher()方法中一开始就初始化了的变量,并在检查完当前是否是文件上传后重新赋值,那就很好猜了,这块的逻辑就是清除产生的临时文件
OK,本篇文章暂告一段落,本人才疏学浅,只领会了这些,如果以后能有更深的理解,我会回来更新的
如果你对SpringMVC有什么不同的看法的话,欢迎来评论区讨论,不吝赐教