SpringMVC的执行流程及源码简单解析

来源:互联网 发布:ubuntu mysql使用 编辑:程序博客网 时间:2024/05/09 09:23

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…)