首页 > 其他分享 >springBoot 获取注解参数的原理

springBoot 获取注解参数的原理

时间:2022-08-27 12:55:06浏览次数:70  
标签:springBoot 方法 request 获取 参数 注解 parameter 类中

springBoot 获取注解参数的原理

原理图

  1. 先得到请求的request

  2. 在获取可以处理请求的方法的Mapping映射器

     DispatcherServlet中的
         doDispatch方法
            // Determine handler for the current request.
            mappedHandler = getHandler(processedRequest);
    
  3. 判断每个参数带有注解是哪个,是否存在相应的解析器

    • 寻找合适的处理适配器

       DispatcherServlet中的
           doDispatch方法		
              // Determine handler adapter for the current request.
              HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
      

    • 寻找可以处理相应注解的处理器
    第一步
    DispatcherServlet中的
        doDispatch方法  
            // Actually invoke the handler.
            mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    
    第二步
    RequestMappingHandlerAdapter中的
        handleInternal方法
        	// No synchronization on session demanded at all...
    			mav = invokeHandlerMethod(request, response, handlerMethod);
    	invokeHandlerMethod方法
            invocableMethod.invokeAndHandle(webRequest, mavContainer);
    
    第三步
    ServletInvocableHandlerMethod中的
        invokeAndHandle方法
        	Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
    
    第四步
    InvocableHandlerMethod类中的
    	invokeForRequest方法
    		Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);//获取请求的参数
    
    第五步
    InvocableHandlerMethod类中的
        getMethodArgumentValues方法
                if (!this.resolvers.supportsParameter(parameter)) {//寻找处理相关注解的处理器,并保存到缓存中 supportsParameter(parameter)从这里进入的
                    throw new IllegalStateException(formatArgumentError(parameter, 								"No suitable resolver"));
                }
            	try {
                args[i] = this.resolvers.resolveArgument(parameter, 	mavContainer, 					request, this.dataBinderFactory);
            }
    
    第六步
    HandlerMethodArgumentResolverComposite类中的
        	@Nullable
            private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter 														parameter) {
                HandlerMethodArgumentResolver result = 	
                    this.argumentResolverCache.get(parameter);//从缓存中获取,开始肯定没有
                if (result == null) {
                    //增强for循环中选择合适的处理器  27个
                    for (HandlerMethodArgumentResolver resolver :
                         this.argumentResolvers) {
                        if (resolver.supportsParameter(parameter)) {
                            result = resolver;
                            //保存到缓存中
                            this.argumentResolverCache.put(parameter, result);
                            break;
                        }
                    }
                }
                return result;
            }
    

    • 通过注解处理器获取参数

      第一步
      InvocableHandlerMethod类中的
          getMethodArgumentValues方法
      
              try {
                  args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); //真正开始获取参数          
              }
      
      第二步
      HandlerMethodArgumentResolverComposite类中的
          resolveArgument方法中
          	//获取参数对应注解的处理器
          	HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
      	getArgumentResolver方法中
          //从缓存中获取,由于开始的之前往缓存中存入了,所以现在可以直接拿,如果没有下面还有可以循环寻找
              HandlerMethodArgumentResolver result = 		    		
              				this.argumentResolverCache.get(parameter);
          
          
      AbstractNamedValueMethodArgumentResolver类中的
          resolveArgument方法
          	Object resolvedName = 
          		resolveEmbeddedValuesAndExpressions(namedValueInfo.name);//获取参数名
      		Object arg = resolveName(resolvedName.toString(), 
                                       nestedParameter, webRequest);//获取参数值
      
      //具体怎么获取
      PathVariableMethodArgumentResolver类中的
          resolveName方法
          protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
          Map<String, String> uriTemplateVars = (Map<String, String>) request.getAttribute(//直接从request请求域中获取  
              HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
          return (uriTemplateVars != null ? uriTemplateVars.get(name) : null);//在通过参数名称确定是哪一个
      }
      
    • 获取参数完成后,会调用InvocableHandlerMethod来中的doInvoke方法继续反射调用方法

      InvocableHandlerMethod类中的
          doInvoke方法
          	return method.invoke(getBean(), args);
      

标签:springBoot,方法,request,获取,参数,注解,parameter,类中
From: https://www.cnblogs.com/shuisanya/p/16630369.html

相关文章

  • add_argument()方法基本参数使用
    selenium做web自动化时我们想要通过get打开一个页面之前就设置好一些基本参数,需要通过add_argument()方法来设置,下面以一个简单的不展示窗口为例。option=webdriver.C......
  • 【IAP Kit】应用内支付订单参数相关问题解析
    ​1、创建的订单orderId长度是多少?答:orderId的长度最大是255。 2、InappPurchaseDetails中orderId和payOrderId有什么区别呢?答:orderId和payOrderId这两者的区别如下:o......
  • 78、使用Jenkins Docker 部署SpringBoot项目
    1、centOS安装Docker1、更新软件源:yumupdate2、卸载旧版本:yumremovedockerdocker-commondocker-selinuxdocker-engine3、安装软件包:yuminstall-yyum-utils......
  • SpringBoot集成thymeleaf不生效问题
    场景:在做springBoot整合Theamleaf时,用了@RestController注解,在进行试图渲染的过程中,遇到试图没有渲染成功,找到了原因,记录一下。 第一种情况:使用@RestController注解pac......
  • 一文了解SpringBoot如何开启热部署
    一文了解SpringBoot如何开启热部署本专栏将从基础开始,循序渐进,以实战为线索,逐步深入SpringBoot相关知识相关知识,打造完整的云原生学习步骤,提升工程化编码能力和思维......
  • SpringBoot集成knife4j
    <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.3</version></dependency>......
  • springboot 使用 JSR303 校验
    JSR303用于后端校验前端传来的数据如何使用引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation<......
  • Max_connect_errors – MySQL性能参数详解
    Max_connect_errors–MySQL性能参数详解_wulantian的博客-CSDN博客_max_connect_errors https://blog.csdn.net/wulantian/article/details/9670957max_connect_error......
  • stream() 参数拆分
    publicstaticvoidmain(String[]args){List<String>list=newArrayList<String>(){{this.add("a,b");......
  • 实际参数和形式参数的区别
    实际参数是出现在函数调用圆括号中的表达式.形式参数是函数定义的函数头中声明的变量.#include<stdio.h>#defineLIMIT65voidstarbar(void)//函数定义{intco......