简单聊一下springmvc执行流程是什么样的——小布

121 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

黑夜.jpg

SpringMVC 常用组件

DispatcherServlet:前端控制器,不需要工程师开发,由框架提供。

作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求

HandlerMapping:处理器映射器,不需要工程师开发,由框架提供。

作用:根据请求的 url、method 等信息查找 Handler,即控制器方法

Handler:处理器,需要工程师开发

作用:在 DispatcherServlet 的控制下 Handler 对具体的用户请求进行处理

HandlerAdapter:处理器适配器,不需要工程师开发,由框架提供

作用:通过 HandlerAdapter 对处理器(控制器方法)进行执行

ViewResolver:视图解析器,不需要工程师开发,由框架提供

作用:进行视图解析,得到相应的视图,例如:ThymeleafView、InternalResourceView、RedirectView

View:视图

作用:将模型数据通过页面展示给用户

SpringMvc具体执行流程详解

(1)用户发送请求至前端控制器 DispatcherServlet;

(2) DispatcherServlet 收到请求后,调用 HandlerMapping 处理器映射器,请求获取 Handle;

(3)处理器映射器根据请求 url 找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet;

(4)DispatcherServlet 调用 HandlerAdapter 处理器适配器;

(5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);

(6)Handler 执行完成返回 ModelAndView;

(7) HandlerAdapter 将 Handler 执 行 结 果 ModelAndView 返 回 给DispatcherServlet;

(8)DispatcherServlet 将 ModelAndView 传给 ViewResolver 视图解析器进行解析;

(9)ViewResolver 解析后返回具体 View;

(10)DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中)

(11)DispatcherServlet 响应用户。

image.png

HttpServlet 部分源码 该类将 service 方法进行了重载,把 ServletRequest 转换成了 HttpServletRequest,然后对不同的请求方式进行了不同的处理。 在 FrameworkServlet 类中重写了所有处理各种请求方式的方法:doXxx

    if (!(req instanceof HttpServletRequest &&
            res instanceof HttpServletResponse)) {
        throw new ServletException("non-HTTP request or response");
    }

	// 将 ServletRequest 转换为 HttpServletRequest
    request = (HttpServletRequest) req;
	// 将 ServletResponse 转换为 HttpServletResponse
    response = (HttpServletResponse) res;

    service(request, response);
}

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	// 获取请求方式
    String method = req.getMethod();

	// 判断请求方式
    if (method.equals(METHOD_GET)) {
        long lastModified = getLastModified(req);
        if (lastModified == -1) {
            // servlet doesn't support if-modified-since, no reason
            // to go through further expensive logic
            doGet(req, resp);
        } else {
            long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
            if (ifModifiedSince < lastModified) {
                // If the servlet mod time is later, call doGet()
                // Round down to the nearest second for a proper compare
                // A ifModifiedSince of -1 will always be less
                maybeSetLastModified(resp, lastModified);
                doGet(req, resp);
            } else {
                resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            }
        }

    } else if (method.equals(METHOD_HEAD)) {
        long lastModified = getLastModified(req);
        maybeSetLastModified(resp, lastModified);
        doHead(req, resp);

    } else if (method.equals(METHOD_POST)) {
        doPost(req, resp);
        
    } else if (method.equals(METHOD_PUT)) {
        doPut(req, resp);
        
    } else if (method.equals(METHOD_DELETE)) {
        doDelete(req, resp);
        
    } else if (method.equals(METHOD_OPTIONS)) {
        doOptions(req,resp);
        
    } else if (method.equals(METHOD_TRACE)) {
        doTrace(req,resp);
        
    } else {
        //
        // Note that this means NO servlet supports whatever
        // method was requested, anywhere on this server.
        //
        String errMsg = lStrings.getString("http.method_not_implemented");
        Object[] errArgs = new Object[1];
        errArgs[0] = method;
        errMsg = MessageFormat.format(errMsg, errArgs);
        
        resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
    }
}

}

以上就是本人对于Springmvc执行流程的的个人见解,今天的分享就到这,我们下期再见😀~~~///(^v^)~~~