springmvc源码部分理解

目录

初始化

处理请求

总结:


主要还是借鉴了很多大佬的分析,参考如下:

完整版:https://www.cnblogs.com/zgwjava/p/11040154.html

分步骤一:https://blog.youkuaiyun.com/gududedabai/article/details/83352106

分步骤一:https://blog.youkuaiyun.com/gududedabai/article/details/83375156

详细版:https://blog.youkuaiyun.com/qq_38410730/article/details/79507465

执行流程

 

从代码角度看:

时序图

初始化

DispatcherServlet.onRefresh()

 protected void onRefresh(ApplicationContext context) {
         this.initStrategies(context);
     }
 ​
 //根据web.xml中配置的和默认的设置初始化
 protected void initStrategies(ApplicationContext context) {
     this.initMultipartResolver(context);    //上传文件相关
     this.initLocaleResolver(context);   //default
     this.initThemeResolver(context);    //default
     this.initHandlerMappings(context);  //获取handlerMapping s
     this.initHandlerAdapters(context);  //获取handlerAdapter s
     this.initHandlerExceptionResolvers(context);    //获取异常处理
     this.initRequestToViewNameTranslator(context);  //defaut
     this.initViewResolvers(context);    //配置的试图解析器
     this.initFlashMapManager(context);  //default-->SessionFlashMapManager
 }
 ​
 //拿上面的initHandlerMappings举个例子  逻辑差不多 都是初始化
 private void initHandlerMappings(ApplicationContext context) {
     this.handlerMappings = null;
     if (this.detectAllHandlerMappings) {    //web.xml中DispatcherServlet的配置来,默认是true,代表拦截全部实现了handlerMapping接口的bean,如果是false则只找名字为handlerMapping的bean
         //返回指定类型和子类型的所有bean
         Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
         if (!matchingBeans.isEmpty()) {
             // map to list 放到属性handlerMappings中。
             this.handlerMappings = new ArrayList(matchingBeans.values());
             //排序 底层是Arrays.sort(list,comparator);
             //AnnotationAwareOrderComparator就是那个comparator. 具体什么规则没有去看了
             AnnotationAwareOrderComparator.sort(this.handlerMappings);
         }
     } else {
         try {
             HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
             this.handlerMappings = Collections.singletonList(hm);
         } catch (NoSuchBeanDefinitionException var3) {
         }
     }
 ​
     //如果还未空,则获取default的
     if (this.handlerMappings == null) {
         this.handlerMappings = this.getDefaultStrategies(context, HandlerMapping.class);
         if (this.logger.isTraceEnabled()) {
             this.logger.trace("No HandlerMappings declared for servlet '" + this.getServletName() + "': using default strategies from DispatcherServlet.properties");
         }
     }
 ​
 }

处理请求

DispatcherServlet.doDispatch()

//核心是DispatcherServlet的doDispatch方法 ,前面会有一些init省略了
 //最早是从servlet.service(request, response);最终到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 {
          //1. 如果是MultipartContent类型则转换为MultiHttpServletRequest类型的request
          processedRequest = checkMultipart(request);
          multipartRequestParsed = (processedRequest != request);
 ​
          // 2.确定当前请求的处理程序,根据request寻找对应的handler
          mappedHandler = getHandler(processedRequest);
          if (mappedHandler == null || mappedHandler.getHandler() == null) {
             noHandlerFound(processedRequest, response);
             return;
          }
 ​
          // 3.根据处理器获取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;
             }
          }
          //4. 拦截器preHandle方法前置处理
          if (!mappedHandler.applyPreHandle(processedRequest, response)) {
             return;
          }
 ​
          // 5. 执行handler 返回modelAndView, 像静态资源就没有mv
          mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
 ​
          if (asyncManager.isConcurrentHandlingStarted()) {
             return;
          }
          // 结果视图对象的处理
          applyDefaultViewName(processedRequest, mv);
         // 6. 拦截器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);
       }
       // 7. 处理最终结果 渲染视图等
        //里面主要是render方法,处理repsonse, 遍历把结果值放到request域中
       processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    }
    catch (Exception ex) {
        // 如果抛错了还是会执行 afterCompletion 返回通知
       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 {
          // 如果是上传文件 则还需要释放文件资源
          if (multipartRequestParsed) {
             cleanupMultipart(processedRequest);
          }
       }
    }
 }

总结:

  1. checkMultipart():判断是否有上传文件,如果有则最后需要释放资源

  2. getHandler() : 在初始化后的handlerMappings中遍历获取handler。

    1. 静态资源是在SimpleUrlHandlerMapping中找

    2. 像queryUser这种请求是在RequestMappingHandlerMapping中找

  3. getHandlerAdapter() :根据上一步找到的handler在handlerAdapters找对应的Adapter。

    1. 通俗的说就是手机插usb有很多接口,type-c, ligntning, micro 等,目的都是转成usb,但是需要不同的适配器来转。

    2. 静态资源是在HttpRequestHandlerAdapter中找

    3. 像queryUser这种请求是在RequestMappingHandlerAdaptor中找

  4. applyPreHandle() :interceptors(多个拦截器)的前置处理

  5. handle():反射执行handler

  6. applyPostHandle():interceptors(多个拦截器)的后置处理

  7. processDisPatchResult():组装结果到response

  8. triggerAfterCompletion() :interceptors(多个拦截器)的返回处理

  9. cleanMultipart():根据第一步判断的,如果是有文件,则要释放资源

执行过程中充分体现了aop(4前置通知,6后置通知,8返回通知)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值