spring mvc 工作流程

图片来源于网络,辅助理解

1、浏览器发送请求到服务端,dispatcherServlet接收到请求,调用HandlerMapping。

HandlerMapping返回 处理器执行链(HandlerExecutionChain)里边包含要具体调用的controller以及controller的哪个方法。还有需要执行的拦截器。

2、dispacherServlet 根据HandlerExecutionCHain 找到具体的HandlerAdapter。

然后再执行HandlerExecutionCHain里包含的拦截器,如果拦截器返回false。请求到此结束。

3、如果拦截器返回true,dispacherservlet再调用刚才找到的HandlerAdapter。

HandlerAdapter返回一个ModelAndView对象。

4、dispatcherServlet调用ViewResolver解析视图。返回View对象。

dispacherServlet渲染视图图,将数据填充到视图中。相应客户端。

下面是DispatcherServlet调用doDispatch方法的部分源码。
复制代码
// DispatcherServlet.doDispatch (核心骨架)
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    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);
            // 1. 找到处理该请求的Handler执行链
            mappedHandler = getHandler(processedRequest);
            if (mappedHandler == null) {
                noHandlerFound(processedRequest, response);
                return;
            }
            // 2. 找到能执行该Handler的Adapter
            HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
            // 3. 处理Last-Modified
            String method = request.getMethod();
            boolean isGet = HttpMethod.GET.matches(method);
            if (isGet || HttpMethod.HEAD.matches(method)) {
                long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                    return;
                }
            }
            // 4. 执行拦截器preHandle
            if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                return;
            }
            // 5. 真正调用Controller方法
            mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
            // 6. 异步请求处理时,直接返回不渲染
            if (asyncManager.isConcurrentHandlingStarted()) {
                return;
            }
            // 7. 设置默认视图名称(如果Controller没指定)
            applyDefaultViewName(processedRequest, mv);
            // 8. 执行拦截器postHandle
            mappedHandler.applyPostHandle(processedRequest, response, mv);
        }
        catch (Exception ex) {
            dispatchException = ex;
        }
        catch (Throwable err) {
            dispatchException = new NestedServletException("Handler dispatch failed", err);
        }
        // 9. 统一处理结果:异常解析 + 视图渲染 + afterCompletion
        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    }
    catch (Exception ex) {
        triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
    }
}
相关推荐
SL_staff1 小时前
BI大屏嵌入MES的登录态难题:JVS统一账号体系实战解法
java·数据分析·数据可视化
乌暮1 小时前
综合案例:宠物电商系统
java·开发语言·spring·mvc·restful·1024程序员节
VimorphTech2 小时前
一段字幕太长,怎样拆句并安排显示时间?
java·spring boot
万联WANFLOW2 小时前
Kimi K3.1 Pro 接口接入指南:模型选型、费用计算与零数据保留
java·spring boot·python·安全·spring·大模型
织码weavecodes2 小时前
新闻资讯模块设计:内容发布、阅读计数与附件鉴权
java·服务器·数据库
学到老活到老2 小时前
Spring 事务怎样生效?为什么加了 @Transactional 仍不回滚?
java·spring
学到老活到老2 小时前
Spring 怎样创建 Bean?@Autowired 在哪一步生效?
java·spring
用户112936112192 小时前
我扫了项目里 739 个 Controller,发现最危险的越权漏洞不是没认证
java
小羊没烦恼!2 小时前
分布式事务 | 使用DTM 的Saga 模式
java·linux·运维·数据库·wpf