写在前面
接在上一篇博客 SpringMVC框架中DispatcherServlet分发请求给对应处理器的流程 之后,我们就要开始逐步揭开我们最常用的 @RequestMapping 注解的神秘面纱。
-
我们将一起了解被 @RequestMapping 注解的方法是如何“注册”到 DispatcherServlet 中的?
-
在 http 请求到达服务器之后,又是如何找到“合适”的被 @RequestMapping 注解的方法?
-
http 请求的参数是如何变为 @RequestMapping 方法中的参数的?
-
@RequestMapping 方法的返回值又是如何变成我们期望的网页或者内容的?
DispatcherServlet 分发时序图
从左向右看,当我们向 SpringMVC 服务器发起一个请求时,会进入到 DisptacherServlet # doDispatch 中。
- 获取处理器:调用 DisptacherServlet # getHandler,根据 HttpServletRequest 推断出我们需要的“处理器对象”,最终返回 HandlerExecutionChain 对象。
public class HandlerExecutionChain {
// 处理器对象
private final Object handler;
/**
* Return the handler object to execute.
* 正因为是 Object 对象,才需要适配器来对应
*/
public Object getHandler() {
return this.handler;
}
}
-
获取适配器:接着调用 DisptacherServlet # getHandlerAdapter,为处理器对象 HandlerExecutionChain # handler 选择出一个支持处理该对象的适配器。
-
执行适配器/处理器:本文中选出的适配器是 RequestMappingHandlerAdapter,现在就调用该适配器的 handle 方法
MappingRegistry 是 AbstractHandlerMethodMapping<T> 的一个内部类,用来存放 url 和 HandlerMethod 的对应关系,RequestMappingInfo 和 HandlerMethod 的对应关系等,方便根据 url 来获取对应的方法。
总结
小结一下,我们现在可以知道,想要解决开篇的问题,要去哪里找源码和寻求答案了!
如果我们想知道 HttpServletRequest 和 HandlerMethod 的对应关系的 扫描注册 和 匹配获取,我们可以去 RequestMappingHandlerMapping 中去寻找。
如果我们想知道 参数处理 和 结果集处理 的逻辑,我们可以去 RequestMappingHandlerAdapter 中去寻找。