本文最后更新于:2024年4月22日 下午
HandlerMapping的几种实现与HandlerAdapter几种原理及其内部细节剖析
初始化
HandlerMapping和HandlerAdapter初始化流程基本一致
1、DispatcherServlet创建对象后,Tomcat调用初始化回调钩子initServletBean()
2、容器启动完成后,Spring发送事件,执行到DispatcherServlet.onRefresh()
3、onRefresh执行九大组件的初始化
HandlerMapping初始化流程(RequestMappingHandlerMapping为例)
- 创建配置中的HandlerMapping对象3种
- 启动createBean使用IOC创建容器
- 基于Spring的原理,实现了InitializingBean,容器启动后续执行afterPropertiesSet
- 拿到子容器(Web容器)的所有组件,扫描@Controller或者@RequestMapping
- 将分析到的信息放于HandlerMapping的registry对象中,以便后续使用
HandlerMapping的实现类
BeanNameUrlHandlerMapping 以bean的名字作为url路径,进行映射
SimpleUrlHandlerMapping 手动配置url与handler的映射
RequestMappingHandlerMapping 使用注解的形式来标识url与handler的映射,平时这种使用最多,重点分析
RouterFunctionMapping 支持函数式以及webFlux相关的功能
BeanNameUrlHandlerMapping
该实现类可以把IOC容器中name以”/“ 开头的Bean注册为handler,
SimpleUrlHandlerMapping
手动配置url与handler的映射,初始化的时候就注册进去了
RequestMappingHandlerMapping
这是最常用的HandlerMapping实现,通过它,我们可以使用注解的形式来标识url与handler的映射:
AbstractHandlerMethodMapping.initHandlerMethods然后执行到 processCandidateBean->detectHandlerMethods再到交由子类实现getMappingForMethod
RequestMappingHandlerMapping中getMappingForMethod
会去判断实现RequestMapping的方法实现,而加入RequestMappingInfo信息中
RouterFunctionMapping
支持webflux相关
HandlerAdapter的实现类
- HttpRequestHandlerAdapter 判断是否是实现HttpRequestHandler接口
- SimpleControllerHandlerAdapter判断是否实现Controller接口
- RequestMappingHandlerAdapter 判断是不是HandlerMethod,注解类型的都是这种
HttpRequestHandlerAdapter
如果这个处理器实现了 HttpRequestHandler
接口,则使用 HttpRequestHandlerAdapter
调用该处理器的 handleRequest(HttpServletRequest request, HttpServletResponse response)
方法去处理器请求
SimpleControllerHandlerAdapter
和 HttpRequestHandlerAdapter 差不多,如果这个处理器实现了 Controoler
接口,则使用 HttpRequestHandlerAdapter
调用该处理器的 handleRequest(HttpServletRequest request, HttpServletResponse response)
方法去处理器请求,直接返回处理器执行后返回 ModelAndView
RequestMappingHandlerAdapter
实现 BeanFactoryAware、InitializingBean 接口,继承 AbstractHandlerMethodAdapter 抽象类,基于 @RequestMapping
注解的 HandlerMethod 处理器的 HandlerMethodAdapter 实现类
几个主要的属性对象:
HandlerMethodArgumentResolverComposite argumentResolvers
:参数处理器组合对象
HandlerMethodReturnValueHandlerComposite returnValueHandlers
:返回值处理器组合对象
List<HttpMessageConverter<?>> messageConverters
:HTTP 消息转换器集合对象
List<Object> requestResponseBodyAdvice
: RequestResponseAdvice 集合对象
InitializingBean对参数初始化
这个时候会准备参数解析器和返回值处理器
参数解析器和返回值处理器的前置工作
RequestMappingHandlerAdapter.invokeHandlerMethod
未来反射解析目标方法中的每一个值 argumentResolvers
返回值处理器,未来用于处理目标方法执行后的返回值,无论目标方法返回什么会转换为适配器所使用的ModelAndView
把该有的组件组合到ServletInvocableHandlerMethod对象中去,最终使用ServletInvocableHandlerMethod进行invokeAndHandle,将数据最后封装到ModelAndViewContainer中去,最后再将ModelAndViewContainer(临时容器,每一次请求都是新new 的对象,同一次请求期间共享数据)抽取ModelAndView(数据和视图)。
参数解析器
27个参数解析器
ServletInvocableHandlerMethod.invokeAndHandle–>invokeForRequest–>getMethodArgumentValues
返回值处理器
15个返回值处理器
ServletInvocableHandlerMethod.invokeAndHandle
找到 returnValueHandlers 执行handleReturnValue
逻辑依然是以先找到为准
接下来执行后置的视图解析器相关业务流程
视图解析器
核心接口
View 视图
ViewResolver 视图解析
流程分析
HandlerAdapter执行完成后会返回ModelAndView对象(里面包含viewName)
所有ViewResolver去解析viewName,一得到就返回,得到View对象,最后调用VIew对象render渲染