zoukankan      html  css  js  c++  java
  • 001 springmvc概述

    一 . 概述

      springmvc作为一个当前最为流行的mvc框架,从本质的设计上讲还是延续了前端控制器模式来完成整合设计.

        但是springmvc凭借和spring的无缝连接,获得了IOC和AOP的能力,于是功能强大了很多.

      本次,我们需要从原理上说一下springmvc,然后找到一些扩展点,完成对springmvc的学习.


     二 .springmvc的架构

      

    在上面的图中,我们看到了整个springmvc的运行流程.

      我们发现整个流程还是比较复杂的,其实当我们在后面分析的时候,整个流程还会更加的复杂.但是现在我们不需要进行这方面的讲述.

      我们首先来看看整个流程的运行.

    [1]用户向web浏览器发起请求.

    [2]请求转发到前端控制器,进入了springmvc的控制流程之中.

    [3]首先请求转发给{处理器映射器},返回的是一个处理器执行链,其中包括处理器和拦截器.

    [4]前端控制器将这个处理器执行链转发给处理器适配器,进行真正的发放的执行,在这里就有很多的扩展点.

    [5]视图渲染

    我们现在只需要简单的了解这个过程就好了.


    三 . 前端控制器

      springmvc的前端控制器是一个Servlet,我们首先看一下这个Servlet的基本结构.

    下面是整个Springmvc的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); //如果是文件上传,进行请求的转换
    
                    // Determine handler for the current request.
                    mappedHandler = getHandler(processedRequest); //通过请求,寻找对象的处理器映射器
                    if (mappedHandler == null || mappedHandler.getHandler() == null) {
                        noHandlerFound(processedRequest, response);  //没有处理器映射器,就说明这个请求的地址没有注册
                        return;
                    }
    
                    // Determine handler adapter for the current request.
              
             //1.首先从处理器映射器之中获取处理器执行链
    // 2/ 然后将处理器执行链转换为处理器适配器
    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; } }           // 处理器执行链的前置拦截行为 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } //调用真正的处理器方法 // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } //转换视图等行为,为域对象存放值等行为 applyDefaultViewName(processedRequest, mv);
              //应该处理器拦截链的后置处理行为 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); } 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); } } } }

    从上面的代码之中,我们整体的分析了springmvc的运转流程,单从流程上讲比较简单,但是后面我们的重点就是

      寻找扩展点和原理,最终比较完成的学习完springmvc.

  • 相关阅读:
    nodejs发送http请求
    Codeforces Round #655 (Div. 2)
    闇の連鎖 树上LCA + 树上差分
    Tree 换根dp
    「水」悠悠碧波 kmp
    HH的项链
    Educational Codeforces Round 90 (Rated for Div. 2)
    巡逻(论为什么第二次求直径要用dp)
    Codeforces Round #651 (Div. 2)
    Treap板子
  • 原文地址:https://www.cnblogs.com/trekxu/p/9114240.html
Copyright © 2011-2022 走看看