SpringMVC流程

0. 前置概念
  • JavaEE体系结构包括四层,从上到下分别是应用层、Web层、业务层、持久层。
  • Struts和SpringMVC是Web层的框架
  • Spring是业务层的框架
  • Hibernate和MyBatis是持久层的框架。
  • SpringMVC是一种基于Java,实现了Web MVC设计模式,请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将Web层进行职责解耦。基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发
1. SpringMVC 流程图

image

具体流程
  1. 发起请求到前端控制器(DispatcherServlet), 任务调度分发作用;
  2. 前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找);
  3. 处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略;
  4. 前端控制器调用处理器适配器去执行Handler
  5. 处理器适配器HandlerAdapter将会根据适配的结果去执行Handler;
  6. Handler执行完成给适配器返回ModelAndView
  7. 处理器适配器向前端控制器返回ModelAndView(ModelAndView是springmvc框架的一个底层对象,包括 Model和view);
  8. 前端控制器请求视图解析器去进行视图解析(根据逻辑视图名解析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可;
  9. 视图解析器向前端控制器返回View;
  10. 前端控制器进行视图渲染 (视图渲染将模型数据(在ModelAndView对象中)填充到request域);
  11. 前端控制器向用户响应结果;
2. doDispatch源码
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 1.用户请求
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    // 判断是否为上传请求的标志
    boolean multipartRequestParsed = false;

    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

    try {
        ModelAndView mv = null;
        Exception dispatchException = null;

        try {
            // 检查是不是上传请求
            processedRequest = checkMultipart(request);
            multipartRequestParsed = (processedRequest != request);

            // Determine handler for the current request.
            // 2.根据Request查询找到handler,3.并返回处理器执行链
            mappedHandler = getHandler(processedRequest);
            if (mappedHandler == null || mappedHandler.getHandler() == null) {
                noHandlerFound(processedRequest, response);
                return;
            }

            // Determine handler adapter for the current request.
            // 4.请求执行handler,根据handler找到HandlerAdapter
            HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

            // Process last-modified header, if supported by the handler.
            // 处理Get、Head请求的Last-Modified
            String method = request.getMethod();
            boolean isGet = "GET".equals(method);
            if (isGet || "HEAD".equals(method)) {
                // 是否使用缓存页面
                long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                if (logger.isDebugEnabled()) {
                    logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                }
                if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                    return;
                }
            }
            // 执行相应的Interceptor的preHandle
            if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                return;
            }

            // Actually invoke the handler.
            // 5.HandlerAdapter执行Handler处理请求(6.返回ModelAndView),
            // 7.返回ModelAndView到DispatcherServlet
            mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
            // 如果需要异步处理直接返回
            if (asyncManager.isConcurrentHandlingStarted()) {
                return;
            }
            // 当mv的view为空时,根据request设置默认view
            applyDefaultViewName(request, mv);
            // 执行相应的Interceptor的preHandle
            mappedHandler.applyPostHandle(processedRequest, response, mv);
        }
        catch (Exception ex) {
            dispatchException = ex;
        }
        // 8、9、10.处理返回结果。(包括处理异常,渲染页面,发出完成通知触发Interceptor的afterCompletion)
        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    }
    catch (Exception ex) {
        triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
    }
    catch (Error err) {
        triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
    }
    finally {
        // 判断是否为异步请求
        if (asyncManager.isConcurrentHandlingStarted()) {
            // Instead of postHandle and afterCompletion
            if (mappedHandler != null) {
                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
            }
        }
        else {
            // Clean up any resources used by a multipart request.
            // 删除上传请求的资源
            if (multipartRequestParsed) {
                cleanupMultipart(processedRequest);
            }
        }
    }
}
3. 实际调用SpringMVC开发涉及部分
  1. DispatcherServlet 在 web.xml 中的部署描述,从而拦截请求到 Spring Web MVC
  2. HandlerMapping 的配置,从而将请求映射到处理器
  3. HandlerAdapter 的配置,从而支持多种类型的处理器
  4. ViewResolver 的配置,从而将逻辑视图名解析为具体视图技术
  5. 处理器(页面控制器)的配置,从而进行功能处理
4. 代码复现(简化版本)

// TODO:GitHub地址

参考
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值