springmvc中HanlderMapping和HandlerAdapter一般是对应出现(并不是一一对应,一个HandlerAdapter可以匹配处理多个HandlerMapping,一个HandlerMapping应该也可以被多个HandlerAdapter处理,但具体配置时应该只是一个,配置多个没有意义,只会被order值小的HandlerAdapter处理)。
从类成员变量this.handlerAdapters中循环匹配HandlerAdapter,找到支持handler的HandlerAdapter。
这里同样对HandlerAdapter的order属性进行了排序,如果配置了多个HandlerAdapter可以支持某一个handler,只会获取order值较小的进行匹配。
RequestMappingHandlerAdapter主要处理常用的Controller里添加了@RequestMapping注解的方法(这里的一个方法就是一个handler),根据handler的类型是否为HandlerMethod进行匹配;
HttpRequestHandlerAdapter主要处理普通HttpRequest请求的handler,当springmvc访问静态资源时,HttpRequestHandlerAdapter会直接调用DefaultServletHttpRequestHandler的handleRequest()
可以看出最终是通过反射来执行Controller里的method。
这个比较简单,执行handler的handleRequest()方法,常用于对静态资源的访问,将请求交给web容器的DefaultServlet处理。
————————————————————————————————————
华丽的分割线。
对HandlerMapping和HandlerAdapter深入分析后发现,HandlerMapping和HandlerAdapter是解耦的,并不存在对应的关系。
HandlerMapping只关心请求URL与处理的handler如何映射,作用是将请求URL映射到handler上,至于handler如何处理(直接调用执行还是交给HandlerAdapter处理或者是其他方式),并不关心;
HandlerAdapter只关心是否能够匹配上handler的类型,匹配上了之后,就去调用执行handler,至于handler是如何和请求URL映射的,并不关心。
所以,HandlerMapping和HandlerAdapter唯一的关联就是handler,但HandlerMapping和HandlerAdapter之间,不存在任何耦合的地方。
之前的认为HandlerMapping和HandlerAdapter存在对应关系的理解,是错误的。基本使用一般是根据需求各配置一个。
HandlerMapping将请求映射到对应的handler后,去匹配HandlerAdapter,找到对应的HandlerAdapter将handler交给HandlerAdapter处理:


从类成员变量this.handlerAdapters中循环匹配HandlerAdapter,找到支持handler的HandlerAdapter。
this.handlerAdapters的赋值在DispatcherServlet的初始化的时候:

这里同样对HandlerAdapter的order属性进行了排序,如果配置了多个HandlerAdapter可以支持某一个handler,只会获取order值较小的进行匹配。
再来看看HandlerAdapter的supports()方法,不同的HandlerAdapter的supports()方法实现也不一样,这里来看看其中两种:
1.RequestMappingHandlerAdapter:


RequestMappingHandlerAdapter主要处理常用的Controller里添加了@RequestMapping注解的方法(这里的一个方法就是一个handler),根据handler的类型是否为HandlerMethod进行匹配;
2.HttpRequestHandlerAdapter:

HttpRequestHandlerAdapter主要处理普通HttpRequest请求的handler,当springmvc访问静态资源时,HttpRequestHandlerAdapter会直接调用DefaultServletHttpRequestHandler的handleRequest()
方法,将请求交给web容器的DefaultServlet处理。
这里匹配handler类型为HttpRequestHandler的handler。
再回到DispatcherServlet继续往下看,获取到HandlerAdapter后,由HandlerAdapter来执行具体的handler:

spingmvc在这里使用了适配器设计模式。HandlerMapping映射请求到具体的handler后,并没有直接进行调用处理,而是将handler交给了可以支持的HandlerAdapter,由HandlerAdapter来进行具体的调用。这是因为handler的类型有多种,可以是method、controller、servlet等,使用适配器模式可以使DispatcherServlet统一透明的对handler进行处理。
还是来看看其中两个Adapter的handle()方法处理:
1.RequestMappingHandlerAdapter:


可以看出最终是通过反射来执行Controller里的method。
2.HttpRequestHandlerAdapter:

这个比较简单,执行handler的handleRequest()方法,常用于对静态资源的访问,将请求交给web容器的DefaultServlet处理。
HandlerAdapter执行完后得到的是一个ModelAndView对象,这个对象将处理将请求结果映射到具体的视图,这个下一篇文章将会接着分析。