Spring MVC 梳理 - handlerMapping和handlerAdapter分析

时间:2021-10-28 14:33:30
  1. 参考图片
    1. Spring MVC 梳理 - handlerMapping和handlerAdapter分析
  2.   

    综上所述我们来猜测一下spring mvc 中根据URL找到处理器Controller中相应方法的流程

    ①:获取Request的URL

    ②:从UrlLookup这个map中找到相应的requestMappingInfo

    ③:如果没找到则遍历所有requestMappingInfo的信息直到找到匹配的requestMappingInfo

    ④:根据requestMappingInfo到mappingLookup中找到handlerMethod

  3. Spring mvc是如何通过URL查找到对应的处理器controller以及对应的方法尼?需要知道以下3个核心接口handlerMapping,handlerAdapter,RequestCondition我们不具体分析相应接口的实现以及具体逻辑,过程相当复杂,1到2句话说

    不清楚,这里给大家留一个直观的考量。

  4. @RequestMapping来标识访问路径,我们以此模板给大家量化分析url查询处理器controller以及相应方法的过程

    handlerMapping:负责查找URL对应的处理器Controller

    RequestMappingInfo:根据注解@RequestMapping生成方法匹配策略

    handlerAdapter:负责绑定参数,执行请求,处理返回值

    1. handlerMapping 接口就一个方法返回HandlerExecutionChain
    2. HandlerExecutionChain包含hanlder、interrupter
    3. 一个处理器中+内部N个方法== N个Handler
    4. M个处理器=M×N个Handler
    5. M×N个Hanlder存放在handlerMappings中
    6. 在DispatcherServlte的servlet初始化中(调用init()方法)中调用onRefresh()完成handlerMappings的初始化

    7. DispatcherServlte会根据handlerMapping与已经注册好了的HandlerAdapter一一匹配,看哪一种HandlerAdapter是支持该handlerMapping类型的,

      如果找到了其中一种HandlerAdapter是支持传过来的handlerMapping类型,那么该HandlerAdapter会调用自己的handle方法,handle方法运用Java的反射机制执行controller的具体方法来获得ModelAndView

  5. 最后说一下RequestMappingHandlerMapping并不是默认的查找处理器方法的策略,他是通过  <mvc:annotation-driven />配置完成容器注册的

  6. 参考 https://www.cnblogs.com/huxuhong/p/7245690.html
  7. spingmvc 执行流程中请求访问时处理器映射器会返回具体的执行链(就是一条符合映射规则的所有拦截器和映射器的列表,你的请求的处理流程就是围绕着这条执行链走的,列表的最后一个元素就是你的处理器对象,执行顺序:先正向---后反向---再反向,详细的你可以查一下springmvc的拦截器执行流程),所以说我个人认为适配器认为是设计模式上的一种规范,可以简单理解为是用来调用目标方法的。

    handlerMapping有很多种:AbstractDetectingUrlHandlerMapping, AbstractHandlerMapping, AbstractHandlerMethodMapping, AbstractUrlHandlerMapping, BeanNameUrlHandlerMapping, RequestMappingHandlerMapping, RequestMappingInfoHandlerMapping, SimpleUrlHandlerMapping, WebSocketHandlerMapping

    常用的几个: BeanNameUrlHandlerMapping, RequestMappingHandlerMappingSimpleUrlHandlerMapping,当然你不注册,框架也会有默认加载映射器,具体配置在自带的某个配置文件里,可以找到的

    处理器映射器作用:先说个场景,当你在写一个处理器的时候,框架提供给你了很多种方式(1.可以通过RequestMappingHandlerMapping使扫描指定目录,使用注解的的方式创建处理器,@Contraller 标记一个处理器,@requestMapping关联url与具体的调用方法。2.你也可以通SimpleUrlHandlerMapping在xml中配置的的方式注册一个处理器,里面写上url与具体的处理器的具体映射关系。3,你还可以通过BeanNameUrlHandlerMapping,将请求的url与BeanNameUrlHandlerMapping的节点的name值加上处理器的name值比对的方式找到具体的某个处理器,。。。。。。),所以面对这些情况,你具体用的哪一种方式核心控制器是不知道的,即使知道它也是处理不了的(因为它没有处理这些情况的代码功能)这时就需要你告诉他了,假如当你在springmvc.xml中注册了一个映射器,例如注解的映射器,当框架加载xml生成子容器的时候,发现这个映射器的时候框架就会明白原来你在项目中用了注解,它就会调用扫描器去扫描你告诉它的目录地址,将注解解析成对象放到容器中,同时保存url与具体的方法的映射关系。假如你注册的是BeanNameUrlHandlerMapping它就知道该去配置文件中去解析你的处理器,并使用拼接的方式保存与url进行匹对的规则。。。。。。。。

    至于适配器本质上其实就是一接口,主要作用就是提供框架调用你的具体的处理器和传递数据用的,跟设计模式里的适配器的作用是一个道理(但又不完全相同,因为只要你能自定义方法名,就说明不是简单的通过接口方法直接调用目标类方法的,应该是反射方式实现的)。因为在框架中是不可能写死的,简单的认为通过接口调用你的实现类中的方法(注解除外,注解大概应该是通过方法对象的反射实现的);

  8. 参考 https://q.cnblogs.com/q/107148/