简单直接让你也读懂springmvc源码分析(3)-- HandlerAdapter

关于springboot整合springmvc的源码分析可以参考以下系列文章:

  1. springboot整合springmvc源码分析(1)--前言
  2. springboot整合springmvc源码分析(2)--承上启下
  3. springboot整合springmvc源码分析(3)--直击内容 

该源码分析系列文章分如下章节:

  1. springmvc源码分析(1)-- DispatcherServlet
  2. springmvc源码分析(2)-- HandlerMapping
  3. springmvc源码分析(3)-- HandlerAdapter
  4. springmvc源码分析(3.1)-- HandlerMethodReturnValueHandler
  5. springmvc源码分析(4)-- ViewResolver

HandlerAdapter默认有4种实现的适配器,其中包括对(Controller/HttpRequestHandler/Servlet)的适配,起名是(SimpleControllerHandlerAdapter/HttpRequestHandlerAdapter/SimpleServletHandlerAdapter)不过这三个已经很少在使用,目前最常用的当属适配RequestMapping的适配器RequestMappingHandlerAdapter

HandlerAdapter接口有三个方法:

boolean supports(Object handler);
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
long getLastModified(HttpServletRequest request, Object handler);

supports表示支持的所适配的Handler

handle执行逻辑方法返回ModelAndView 

那本章自然是从这个比较常用的适配器RequestMappingHandlerAdapter讲起。

我们来看下他的supports方法:

这里就表明它仅支持适配HandlerMethod

我们还是像上一章那样springmvc源码分析(2)-- HandlerMapping,直接从springboot的WebMvcAutoConfiguration这里开始:

这里把RequestMappingHandlerAdapter交由spring管理,我们看看RequestMappingHandlerAdapter的类继承关系:

它实现了一个InitializingBean接口,所以我们直接着手afterPropertiesSet方法开始:

首先这里调用了initControllerAdviceCache方法:

 

ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());

查找出所有增强类,就如springmvc实用篇 -- @ControllerAdvice该章使用到的,然后接着遍历

获取该增强类的@ModelAttribute并放入map

 MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);

以及获取@InitBinder并放入map

 MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);

接着判断该增强类是否实现了RequestBodyAdvice或者ResponseBodyAdvice后放入requestResponseBodyAdvice

接着回到:

下面就是进行一系列默认的HandlerMethodArgumentResolver创建和获取以及HandlerMethodReturnValueHandler,其中就包括我们springmvc实用篇 -- WebMvcConfigurer这一章中所自定义的配置

经过上面一系列动作整个RequestMappingHandlerAdapter就已经构建完了。

接着回到第一章springmvc源码分析(1)-- DispatcherServlet这里:

获取所有实现HandlerAdapter接口的bean ,然后放入DispatcherServlet.handlerAdapters的list里供选择适配器时使用

接着回到第一章springmvc源码分析(1)-- DispatcherServlet调用选择适配器:

循环遍历所有适配器,然后调用supports方法判断是否支持当前传入的handler,毫无疑问这里将返回RequestMappingHandlerAdapter这个适配器。

拿到处理器适配器之后就进入真正的controller调用和返回modelAndView

在调用之前将进行拦截器的applyPreHandle调用mappedHandler.applyPreHandle:

接着AbstractHandlerMethodAdapter.handle:

实际这里还是调用RequestMappingHandlerAdapter.handleInternal方法:

接着就是调用RequestMappingHandlerAdapter.invokeHandlerMethod,该方法下一系列操作包括加载argumentResolvers、returnValueHandlers、以及controllerAdvice方法的调用等等,这里就不对这些进行分析了,后续有时间再另开文章专门分析,我们关注它什么时候进行调用我们的controller,下面是该方法的部分代码:

接着执行:invokeAndHandle

然后接着:InvocableHandlerMethod.invokeForRequest

InvocableHandlerMethod.doInvoke :

到这里我们明显看到反射调用我们的controller的方法,将调用结果进行返回

InvocableHandlerMethod.invokeForRequest拿到返回值之后往下走就是调用HandlerMethodReturnValueHandlerComposite.handleReturnValue:

 selectHandler选择一个合适的HandlerMethodReturnValueHandler

这里我们当是选择了RequestResponseBodyMethodProcessor(因为我们controller用的是@ResponseBody的话),具体参考springmvc源码分析(3.1)-- HandlerMethodReturnValueHandler; 

当我们选择的是RequestResponseBodyMethodProcessor那么在执行handler.handleReturnValue的时候基本就已经完成了浏览器的响应。然后回到下面:

调用getModelAndView进行获取ModelAndView:

圈红位置我们注意到,如果选择的是RequestResponseBodyMethodProcessor那么这里将会是true,那么就将返回null,没有modelAndView,也就是不会再进入视图解析器,也就是完成了我们整个接口的调用和响应,如果选择的比如是ModelAndViewMethodReturnValueHandler,那么这里就会将会构造modelAndView然后进行返回,接着就是进入视图解析器的解析渲染了。

至此我们的适配器调用流程就已经很明朗了

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值