HandlerMapping 与 HandlerAdapter
HandlerMapping 和 HandlerAdapter 都是 interface ,DefaultAnnotationHandlerMapping 和 RequestMappingHandlerMapping 为 HandlerMapping 的实现类,AnnotationMethodHandlerAdapter 和 RequestMappingHandlerAdapter 为 HandlerAdapter 的实现类。
简要来说,HandlerMapping 所起的作用就是将 handler method(即使用了 @RequestMapping ,或 @GetMapping 或 PostMapping 注释的方法)映射到指定的 URL 上。
HandlerAdapter 是用来调用使用了 @RequestMapping (或者 @GetMapping ,@PostMapping 等注解)注解的方法。因为 DispatcherServlet 作为一个 Front Controller (前端控制器),会接收所有的 request,并且将 request 转发给相对应的 Controller ,然后调用符合要求的 handler method 来进行业务处理。但是 DispatcherServlet 无法直接调用 handler method,这时候就需要通过 HandlerAdapter 的帮助来调用符合要求的 handler method。
所以说,HandlerMapping 和 HandlerAdapter 是相互配合工作的,HandlerMapping 用来映射,HandlerAdapter 用来调用所映射到的 handler method,两者各司其职,缺一不可。
所以在没有声明相关的 HandlerMapping 或 HandlerAdapter 的 Web Spring Application 中,@RequestMapping 等的注解将不起作用。
DefaultAnnotationHandlerMapping 与 AnnotationMethodHandlerAdapter
DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter 分别为 HandlerMapping 和 HandlerAdapter 的实现类。
总的来说, DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter 分别帮助 Spring MVC(或者说 DispatcherServlet)将所接收的 request 转发给相对应的 controller,并调用相关的 handler method 来完成业务处理。
注意:DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter 从 Spring 3.2 开始就已经被标注为 deprecated ,取而代之的是 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter。
RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter
RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter 在 Spring 3.1 的时候出现,并在 Spring 3.2 中正式代替了 DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter。其作用与 DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter 相差无几。
RequestMappingHandlerMapping 通过创建 RequestMappingInfo 实例来维护 URL 与 handler 之间的关系
之所以要让 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter 代替 DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter ,Spring Doc 给出的理由简要归结起来有两点:
- RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter 更加灵活,能够更好地去定制或扩展
- RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter 使用了 HandlerMethod 的概念
启用 HandlerMapping 与 HandlerAdapter
在配置类中声明
//在 Java 中注册 DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter
@Configuration
public class DispatcherServletConfig {
@Bean
public DefaultAnnotationHandlerMapping defaultAnnotationHandlerMapping(){
return new DefaultAnnotationHandlerMapping();
}
@Bean
public AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter(){
return new AnnotationMethodHandlerAdapter();
}
}
//在 Java 中注册 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter
@Configuration
public class DispatcherServletConfig {
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping(){
return new RequestMappingHandlerMapping();
}
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(){
return new RequestMappingHandlerAdapter();
}
}
在 xml 中声明
<beans ...>
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
</beans>
或者
<beans ...>
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
</beans>
通过 <mvc:annotation-driven/>
- 对于 Spring 3.1 及之前的版本, <mvc:annotation-driven /> 将会自动注册 DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter 这两个 bean(因为此时这两个 bean 还没有被遗弃)
- 对于 Spring 3.1 之后的版本,<mvc:annotation-driven /> 将会自动注册 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter 这两个 bean(因为此时这两个 bean 已经用来代替 DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter 了)
<beans ...>
...
<mvc:annotation-driven />
...
</beans>
通过 @EnableWebMvc
从 Spring 3.1 开始,可以使用 @EnableWebMvc(通常与 @Configuration 注解用在一起) 来自动注册 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter
@Configuration
@EnableWebMvc
public class DispatcherServletConfig {
...
}
最后,希望这篇文章能带给你点启发,Have Fun!