SpringMVC请求执行过程

SpringMVC请求执行过程拆分成主要的7步。

请求发起后会进入DispatchServlet中doDispatch。下一篇文章讲解如何进入DispatchServlet中doDispatch,和启动SpringMVC容器时做的前期准备(初始化handlerMappings,handlerAdapters…)。

整体流程:

在这里插入图片描述

组件:

1、前端控制器DispatcherServlet(不需要程序员开发)
作用接收请求,响应结果,相当于转发器,中央处理器。
有了DispatcherServlet减少了其它组件之间的耦合度。

2、处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的url查找Handler

3、处理器适配器HandlerAdapter
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler

4、处理器Handler(需要程序员开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler

5、视图解析器View resolver(不需要程序员开发)
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)

6、视图View(需要程序员开发jsp)
View是一个接口,实现类支持不同的View类型(InternalResourceView、freemarkerView)

一、getHandler

getHandler中遍历handlerMappings获取handler,handlerMappings中包含下图类型的handlerMapping。
在这里插入图片描述
以RequestMappingHandlerMapping为例。其中HandlerMethod包含了请求对应的handler的请求处理方法如图
在这里插入图片描述
查看RequestMappingHandlerMapping
父类RequestMappingInfoHandlerMapping
父类RequestMappingInfoHandlerMapping
父类AbstractHandlerMethodMapping
父类AbstractHandlerMapping

AbstractHandlerMapping 中getHandler->getHandlerInternal(AbstractHandlerMethodMapping)->lookupHandlerMethod(AbstractHandlerMethodMapping)
通过url匹配相应的HandlerMethod
返回handlerMethod类型的对象如下图。
在这里插入图片描述
把获取到的handlerMethod类型的对象传入getHandlerExecutionChain 返回mappedHandler
类型为HandlerExecutionChain其中包含HandlerMethod和所有拦截此请求的拦截器。
在这里插入图片描述

二、getHandlerAdapter

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
遍历三种类型的HandlerAdaper
在这里插入图片描述
以RequestMappingHandlerAdapter类型的HandlerAdapter为例
RequestMappingHandlerAdapter
父类AbstractHandlerMethodAdapter
父类中supports方法判断传入的handler是否为HandlerMethod类型如果能匹配则返回RequestMappingHandlerAdapter类型的HandlerAdapter。在第一步中handler的类型为HandlerMethod类型。所以匹配上RequestMappingHandlerAdapter。
在这里插入图片描述

三、applyPreHandle

执行第一步获取的mappedHandler,遍历执行mappedHandler中getHandler阶段保存的拦截此请求的拦截器的preHandle方法。
在这里插入图片描述
一旦preHandle返回false拦截器链会终止执行,并执行相应拦截器的triggerAfterCompletion
方法,返回false后,
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
会return不会往下继续执行,请求终止,不会执行第四步及以下步骤。

四、ha.handle

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

继续以第二步获取的RequestMappingHandlerAdapter类型的HandlerAdapter为例
执行RequestMappingHandlerAdapter父类AbstractHandlerMethodAdapter的handle方法,继续调用RequestMappingHandlerAdapte的handleInternal
——>invokeHandleMethod(request, response, handlerMethod)
->createRequestMappingMethod 返回requestMappingMethod
为ServletInvocableHandlerMethod类型的对象。

ServletInvocableHandlerMethod
父类InvocableHandlerMethod
父类HandlerMethod

->requestMappingMethod的 invokeAndHandle方法
(ServletInvocableHandlerMethod)。
->invokeForRequest(InvocableHandlerMethod)
执行handler返回执行结果,此步骤就是调用controller中@RequestMapping对应方法。
getModelAndView返回ModleAndView对象。

五、applyDefaultViewName

一旦ModleAndView中有View后applyDefaultViewName不会在给ModleAndView设置默认的view了。

六、applyPostHandle

遍历执行拦截器链中拦截器postHandle方法。

七、processDispatchResult

执行render(mv, request, response)。
创建view对象 把ModelAndView对象赋值给view.
执行resolveViewName,遍历所有viewResolvers,因为项目中使用的freeMarker模板解析器,所以viewResolvers只有freeMarkerViewResolver.
在这里插入图片描述
查看
FreeMarkerViewResolver继承关系,执行resolveViewName
父类AbstractTemplateViewResolver
父类UrlBasedViewResolver
父类AbstractCachingViewResolver
其实执行的父类AbstractCachingViewResolver的resolveViewName
->createView
loadView->buildView(UrlBasedViewResolver)
->AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(getViewClass());
getViewClass获取的是FreeMarkerView。最终返回FreeMarkerView。
在这里插入图片描述
在配置FreeMarkerViewResolver的时候配置的viewClass在这里插入图片描述
执行resolveViewName返回FreeMarkerView后,执行view.render(mv.getModelInternal(), request, response)在这里插入图片描述

FreeMarkerView继承关系
org.springframework.http.web.servlet.view.freemarker.FreeMarkerView
继承了org.springframework.web.servlet.view.freemarker.FreeMarkerView
->AbstractTemplateView
->AbstractUrlBasedView
->AbstractView

其实执行的是AbstractView中的render
->renderMergedOutputModel(org.springframework.web.servlet.view.freemarker.FreeMarkerView重写了renderMergedOutputModel)
->doRender(org.springframework.web.servlet.view.freemarker.FreeMarkerView)
->template.process(model, response.getWriter())替换页面中表达式为具体返回值并返回页面内容到前台。
在这里插入图片描述
还有一个重要的方法exposeHelpers。
子类org.springframework.http.web.servlet.view.freemarker.FreeMarkerView重写了org.springframework.web.servlet.view.freemarker.FreeMarkerView中的exposeHelpers。这里可以统一的往前台赋值。paramMap中放入context_path后,所有FreeMarkerView解析过的视图都可以获取。在这里插入图片描述

执行完render后,最后mappedHandler.triggerAfterCompletion(request, response, null);
遍历执行拦截器链中afterCompletion方法。
在这里插入图片描述

补充:

在DispatchServlet中doDispatch最新执行的
processedRequest = checkMultipart(request);判断当前请求是否满足文件类型的请求。一旦满足将会把请求转为MultipartHttpServletRequest类型的请求。
在这里插入图片描述
multipartResolver配置,添加CommonsMultipartResolver。在这里插入图片描述执行CommonsMultipartResolver中isMultipart.在这里插入图片描述

请求类型为POST请求并且contentType以multipart开头。满足条件转化为MultipartHttpServletRequest类型请求。在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值