Spring WebMVC 版本:5.1.3.RELEASE
定义一个controller
1 | @RequestMapping("dingtalk") |
我们请求http://localhost:9000/dingtalk/contact/authscope
这个URL时会调用该controller的 findContactAuthScope 方法。
那么Spring MVC是怎么实现这个处理流程的呢?
图源:SpringMVC流程架构图
我们知道 DispatcherServlet 类是Spring MVC 的入口,
每次请求都会调用它的 doService 方法,该方法又将请求委托给 doDispatch 方法处理,我们来看doDispatch方法
的实现:
1 | protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { |
第1点getHandler方法的实现:
1 | @Nullable |
RequestMappingHandlerMapping 类用于从@Controller注解所在的类的@RequestMapping注解上
构建(RequestMappingInfo)请求映射信息实例。
可以看到是通过遍历HandlerMapping列表,然后调用每个HandlerMapping接口的getHandler方法,进入
实现该接口的抽象类 AbstractHandlerMapping 重写的getHandler方法实现:
1 | @Override |
进入到AbstractHandlerMethodMapping的getHandlerInternal方法的实现:
1 | @Override |
到这里就查到请求的uri对应的是findContactAuthScope方法。
下一步执行第2点,获取HandlerMethod对应的HandlerAdapter,查看getHandlerAdapter方法实现:
1 | protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { |
下一步执行第3点,调用 AbstractHandlerMethodAdapter的handle方法,最终会调用子类的handleInternal方法,
该方法位于RequestMappingHandlerAdapter:
1 | @Override |
invokeHandlerMethod方法实现:
1 | @Nullable |
在此方法中调用了invokeAndHandle
方法,实现反射调用目标方法并通过 HandlerMethodReturnValueHandler 接口的实现类处理返回结果值,
然后会调用实现了ResponseBodyAdvice 接口的类的beforeBodyWrite方法处理返回值,
最后通过实现了GenericHttpMessageConverter 接口的类将响应body写入输出流信息中。
以上,如有问题欢迎提出!