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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fangxinde/article/details/78226886

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

猜你喜欢

转载自blog.csdn.net/fangxinde/article/details/78226886