首页 > 其他分享 >spring-mvc 请求流程学习

spring-mvc 请求流程学习

时间:2023-10-11 20:47:41浏览次数:31  
标签:web handler spring 流程 springframework mvc org getHandler servlet

参考:01、基础入门-SpringBoot2课程介绍_哔哩哔哩_bilibili

image-20231011172405870

请求进入HttpServlet 的doGet方法

然后通过实现类org.springframework.web.servlet.FrameworkServlet#doGet()

调用 org.springframework.web.servlet.FrameworkServlet#processRequest

----》org.springframework.web.servlet.DispatcherServlet#doService

----》org.springframework.web.servlet.DispatcherServlet#doDispatch

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
      代码1  mappedHandler = getHandler(processedRequest);
      代码2 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        // Actually invoke the handler.
      代码3  mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    }

代码1.根据映射器获取handler

getHandler(processedRequest) 就是 请求处理器映射器获取对应的handler

@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
   if (this.handlerMappings != null) {
      for (HandlerMapping mapping : this.handlerMappings) {
         HandlerExecutionChain handler = mapping.getHandler(request);
         if (handler != null) {
            return handler;
         }
      }
   }
   return null;
}

在默认情况下springmvc 会提供5个

image-20231011174802738

如果是在controller层标注了@RequestMapping 那就是会使用

RequestMappingHandlerMapping


代码2.根据handler 获取处理器适配器

getHandlerAdapter(mappedHandler.getHandler()); 就是 请求处理器映射器获取对应的handler


代码3.执行controller层代码

ha.handle(processedRequest, response, mappedHandler.getHandler());

这里面有个前提就是springmvc如何获取请求入参 比如@PathVariable /@RequestParam

因为此时代码执行到了ha.handle(processedRequest, response, mappedHandler.getHandler());

此时的调用链是

org.springframework.web.servlet.HandlerAdapter#handle

----》org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle

----》org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

----》org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod

protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
                                           HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
    注意点1:if (this.argumentResolvers != null) {
        invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
    }
    注意点2: if (this.returnValueHandlers != null) {
        invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
    }
    注意点3: invocableMethod.invokeAndHandle(webRequest, mavContainer);
    return getModelAndView(mavContainer, modelFactory, webRequest);
}

在上面的代码中里面有着注意点1argumentResolvers 这里面就是用来解析 对应的入参的

通过debug的形式可以发现里面的内容

image-20231011180100764

就举例PathVariableMapMethodArgumentResolver 这里面就标识了注解parameter.getParameterAnnotation(PathVariable.class);

public class PathVariableMapMethodArgumentResolver implements HandlerMethodArgumentResolver {

   @Override
   public boolean supportsParameter(MethodParameter parameter) {
      PathVariable ann = parameter.getParameterAnnotation(PathVariable.class);
      return (ann != null && Map.class.isAssignableFrom(parameter.getParameterType()) &&
            !StringUtils.hasText(ann.value()));
   }

   /**
    * Return a Map with all URI template variables or an empty map.
    */
   @Override
   public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
         NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {

      @SuppressWarnings("unchecked")
      Map<String, String> uriTemplateVars =
            (Map<String, String>) webRequest.getAttribute(
                  HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);

      if (!CollectionUtils.isEmpty(uriTemplateVars)) {
         return new LinkedHashMap<>(uriTemplateVars);
      }
      else {
         return Collections.emptyMap();
      }
   }

}

然后里面还有着 注意点2返回值的returnValueHandlers

这里面的内容有着这里面的就是开头那个流程图图片里的ModeAndView对象

image-20231011180409870

接下来是 注意点3 invocableMethod.invokeAndHandle(webRequest, mavContainer);

org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

--》org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest

--》org.springframework.web.method.support.InvocableHandlerMethod#doInvoke

这里面就是通过反射然后调用controller层代码了


针对于视图解析器上,因为普遍采用的都是前后端分离了,基本都是json数据了,所以暂时不怎么了解了

标签:web,handler,spring,流程,springframework,mvc,org,getHandler,servlet
From: https://www.cnblogs.com/zz0203/p/17758127.html

相关文章

  • SpringBean生命周期
    SpringBean生命周期读源码小方法:先把所有代码块折叠,看整体,再逐步进入局部,忽略异常处理。写简单程序打断点调试。本文主要ref结论生命周期主要的扩展点:实例化(doGetBean()->createBeanInstance()),注入(populate),初始化(initializeBean),销毁。一般processor都是在这些点前后......
  • springboot跨域解决方案
    @BeanpublicCorsFiltercorsFilter(){CorsConfigurationconfig=newCorsConfiguration();config.addAllowedOriginPattern("*");config.setAllowCredentials(true);config.addAllowedMethod("OPTIONS");......
  • 7min到40s:SpringBoot 启动优化实践!
    0背景公司SpringBoot项目在日常开发过程中发现服务启动过程异常缓慢,常常需要6-7分钟才能暴露端口,严重降低开发效率。通过SpringBoot的SpringApplicationRunListener、BeanPostProcessor原理和源码调试等手段排查发现,在Bean扫描和Bean注入这个两个阶段有很大的性能......
  • springMVC @Test方法中如何请求https
    原文链接:https://www.longkui.site/error/springmvc-test-https/4823/0.背景springMVC环境,需要在@Test方法中发送一个https请求,按照格式要求发送了,结果报错org.springframework.web.client.ResourceAccessException:I/OerroronPOSTrequestfor"https://xxxx/xxx/xx:jav......
  • SpringBoot实现CORS跨域的三种方式
    一、实现WebMvcConfigurer接口@ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{/***添加跨域支持*/@OverridepublicvoidaddCorsMappings(CorsRegistryregistry){//允许跨域访问的路径'/**'表示应用的所有方法......
  • spring扫描本项目包下类数量 方法数量
    importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.core.io.Resource;importorg.springframework.core.io.support.PathMatc......
  • Spring Batch 批处理框架,真心强呀!!
    一、SpringBatch介绍SpringBatch是一个轻量级、全面的批处理框架,旨在支持开发对企业系统的日常操作至关重要的健壮的批处理应用程序。SpringBatch建立在人们期望的SpringFramework特性(生产力、基于POJO的开发方法和一般易用性)的基础上,同时使开发人员可以在必要时轻松......
  • Spring Cloud服务之Nacos作为注册中心与配置中心
    1、创建maven父工程管理jar包版本创建maven骨架,删除多余部分文件。只留pom文件,添加依赖<packaging>pom</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>......
  • spring boot视频播放平台,播放视频很卡,有几种方案解决
    1.首先介绍场景:视频播放平台,系统使用Springboot和Vue编写。拥有前台和后台,前台进行视频播放,后台进行视频的上传,也可以上传音乐和图片,功能顺手都做了。2.问题:浏览器播放视频卡顿。视频卡顿问题需要攻克2关。3.解决过程1)第一关:视频文件太大,浏览器加载时间长。采用后端对......
  • 前台首页,导出项目依赖,git介绍和安装,git和其他相关介绍,git工作流程,git常用命令,git忽略
    1前台首页⛺1.1Header.vue<template><divclass="header"><divclass="slogan"><p>老男孩IT教育|帮助有志向的年轻人通过努力学习获得体面的工作和生活</p></div><divclass="nav"><ulclass=......