SpringMVC的执行流程及源码简单解析
SpringMVC 是Spring为展现层提供的基于MVC设计理念的优秀Web框架,通过一套MVC注解,让POJO成为处理请求的控制器,而无需实现任何接口。为了更深刻的理解SpringMVC框架,特通过源码来学习SpringMVC运行流程。
1.下图是SpringMVC一个正常请求的运行流程图:
2.通过源码对流程图进行简单的解析
第一步:发起请求
通过springDispatcherServlet的url-pattern配置对请求进行拦截,确认SpringMVC中是否存在对应的映射。
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--关联springMvc.xml配置文件-->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
第二步:若存在对应的映射,由HandlerMapping获取HandlerExecutionChain对象。
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
第三步:根据getHandlerAdapter(mappedHandler.getHandler())方法获取对应请求的适配器HanderAdapter对象。
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
第四步:调用拦截器PreHandle方法
mappedHandler.applyPreHandle(processedRequest, response)
第五步:调用目标handler的目标方法,得到ModelAndView对象
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
第六步:调用拦截器的postHandler方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
第七步:如果不存在异常,由ViewResolver组件根据ModelAndView对象得到实际的
protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
HttpServletRequest request) throws Exception {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
return null;
}
第八步: 渲染视图
view.render(mv.getModelInternal(), request, response);
第九步:调用拦截器afterCompletion方法
mappedHandler.triggerAfterCompletion(request, response, null);
引用其他博客对组件的解释,便于理解:
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类型(jsp、freemarker、pdf…)