zoukankan      html  css  js  c++  java
  • SpringMVC学习(一)——概念、流程图、源码简析

      学习资料:开涛的《跟我学SpringMVC.pdf》

      众所周知,springMVC是比较常用的web框架,通常整合spring使用。这里抛开spring,单纯的对springMVC做一下总结。

      概念

      HandlerMapping:处理器映射,对请求的URL进行映射为具体的处理器(如果有拦截器也包含拦截器,会将Handler和多个HandlerInterceptor封装为HandlerExecutionChain对象)

      HandlerAdapter:处理器适配器,适配不同类型的处理器,如Controller、AbstractController等

      Handler:处理器,即开发的Controller

      ModeAndView:模型和视图,未来会渲染为具体的视图

      ViewResolver:视图解析器,将逻辑视图名称转化为物理视图

      View:视图

      流程图

      源码简析(摘自DispatcherServlet源码部分)

      由于springMVC的配置本身就上一个servlet,所以跟踪代码doService()=>doDispatcher(),核心代码如下所示,中文注释自己加的

    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 {
                        //对文件上传类型的数据进行处理,使用MultipartResolver解析
                        processedRequest = checkMultipart(request);
                        multipartRequestParsed = (processedRequest != request);
    
                        //使用HandlerMapping进行映射,将一个Handler和多个HandlerInterceptor封装为HandlerExecutionChain对象
                        mappedHandler = getHandler(processedRequest);
                        if (mappedHandler == null || mappedHandler.getHandler() == null) {
                            noHandlerFound(processedRequest, response);
                            return;
                        }
    
                        //根据Handler获取合适的Handler适配器
                        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
                        // Process last-modified header, if supported by the handler.
                        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;
                            }
                        }
    
                        /*
                         * 调用拦截器的preHandle(),返回true继续执行下一个拦截器或处理器,返回false中断流程并执行执行成功的拦截器的afterCompletion()。
                                */
                        if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                            return;
                        }
    
                        //使用HandlerAdapter执行Handler并返回ModeAndView
                        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    
                        if (asyncManager.isConcurrentHandlingStarted()) {
                            return;
                        }
    
                        applyDefaultViewName(processedRequest, mv);
                        //调用拦截器的postHandle()方法
                        mappedHandler.applyPostHandle(processedRequest, response, mv);
                    }
                    catch (Exception ex) {
                        dispatchException = ex;
                    }
                    catch (Throwable err) {
                        // As of 4.3, we're processing Errors thrown from handler methods as well,
                        // making them available for @ExceptionHandler methods and other scenarios.
                        dispatchException = new NestedServletException("Handler dispatch failed", err);
                    }
                    //处理转发结果,包含ModeAndView的视图解析,视图解析后调用拦截器的afterCompletion()函数
                    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
                }
                catch (Exception ex) {
                    triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
                }
                catch (Throwable err) {
                    triggerAfterCompletion(processedRequest, response, mappedHandler,
                            new NestedServletException("Handler processing failed", 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);
                        }
                    }
                }
            }
  • 相关阅读:
    DataReader相关知识点⭐⭐⭐⭐⭐
    C# Distanct List集合
    RePlace函数
    DataTable和DataRow和DataColumn ⭐⭐⭐⭐⭐
    scrapy 基础组件专题(八):scrapy-redis 框架分析
    scrapy 基础组件专题(九):scrapy-redis 源码分析
    scrapy 基础组件专题(七):scrapy 调度器、调度器中间件、自定义调度器
    scrapy 基础组件专题(六):自定义命令
    scrapy 基础组件专题(五):自定义扩展
    scrapy 基础组件专题(四):信号运用
  • 原文地址:https://www.cnblogs.com/douJiangYouTiao888/p/6705855.html
Copyright © 2011-2022 走看看