Spring源码-SpringMVC-HandlerAdapter

总结摘要
SpringMVC HandlerAdapter Introduction

HandlerAdapter 介绍

简介

在 Spring MVC 中,HandlerAdapter 是核心组件之一,负责协调控制器(Handler)的执行流程。它的主要作用是适配不同类型的处理器(Handler),使它们能够统一处理请求。

主要功能

  1. HttpServletRequestHttpServletResponse 转换为处理器所需的参数(如方法参数、模型对象)。
  2. 调用处理器方法(如 @RequestMapping 注解的方法)并执行业务逻辑。
  3. 处理返回结果(如视图名称、ModelAndViewResponseEntity 等),将其转换为统一的 ModelAndView 对象或其他响应形式。

类定义

1
2
3
4
5
6
// org.springframework.web.servlet.HandlerAdapter
public interface HandlerAdapter {
    boolean supports(Object handler); // 判断是否支持当前处理器
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
    long getLastModified(HttpServletRequest request, Object handler); // 可选:资源最后修改时间
}

使用场景

流程

  1. DispatcherServlet 根据请求找到对应的处理器(Handler)。
  2. 遍历已注册的 HandlerAdapter,通过 supports() 方法找到能处理该类型的适配器。
  3. 调用适配器的 handle() 方法执行处理器,并返回 ModelAndView 或直接写入响应。

代码

1
2
3
4
5
6
7
-> org.springframework.web.servlet.DispatcherServlet#doDispatch
    -> 返回找到的第一个 HandlerAdapterorg.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
        -> for-each org.springframework.web.servlet.DispatcherServlet#handlerAdapters
            -> org.springframework.web.servlet.HandlerAdapter#supports
    -> 处理请求中 last-modified header 相关事务
        -> org.springframework.web.servlet.HandlerAdapter#getLastModified
    -> 调用 HandlerAdapter#handle 方法即处理器逻辑org.springframework.web.servlet.HandlerAdapter#handle

常见实现类

HandlerAdapter 与 HandlerMapping 有对应关系。

实现类适用场景支持的处理器类型
RequestMappingHandlerAdapter处理 @Controller
@RequestMapping
方法,支持参数解析、数据绑定、异步处理
HandlerMethod
(注解方法)
SimpleControllerHandlerAdapter适配传统 Controller
接口实现(如 AbstractController
Controller
接口实现类
HttpRequestHandlerAdapter处理静态资源请求、WebSocket 等,通常配合 DefaultServletHttpRequestHandlerHttpRequestHandler
接口实现类
HandlerFunctionAdapter支持 Spring WebFlux 函数式端点(RouterFunction
HandlerFunction
HandlerFunction
函数式处理器
SimpleServletHandlerAdapter直接调用 Servlet
实现类,适用于传统 Servlet 集成
Servlet
接口实现类

RequestMappingHandlerAdapter

简介

RequestMappingHandlerAdapter 是一个请求处理器适配器(Handler Adapter)。在Spring MVC的请求处理流程中,它充当了“适配器”的角色,将用户请求与控制器方法进行匹配,并调用对应的控制器方法来处理请求。

类定义

1
2
3
4
5
6
// Extension of AbstractHandlerMethodAdapter that supports @RequestMapping annotated HandlerMethods.
// org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
		implements BeanFactoryAware, InitializingBean {}
// instanceof HandlerAdapter, InitializingBean
// instanceof WebApplicationObjectSupport, ApplicationObjectSupport

自动配置机制

配置信息 spring-boot-autoconfigure-2.7.18.jar!\META-INF\spring\org.springframework.boot.autoconfigure.AutoConfiguration.imports

具体流程

  1. org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
  2. org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration
  3. org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration#requestMappingHandlerAdapter
  4. org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerAdapter
1
2
3
4
5
6
// org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerAdapter
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
        @Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
        @Qualifier("mvcConversionService") FormattingConversionService conversionService,
        @Qualifier("mvcValidator") Validator validator) {}

初始化

主流程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerAdapter
-> org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#createRequestMappingHandlerAdapter
    -> new RequestMappingHandlerAdapter()
-> 配置 contentNegotiationManager 属性
-> 配置 messageConverters
    -> org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getMessageConverters
        -> 使用委托类配置 messageConvertersorg.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#configureMessageConverters
            -> for-each org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#delegates 调用 delegate.configureMessageConverters(converters)
        -> 配置默认 messageConvertersorg.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addDefaultHttpMessageConverters
            -> 配置默认 messageConverters包括 ByteArrayHttpMessageConverterStringHttpMessageConverter 
            -> XML 格式消息转换器配置if (!shouldIgnoreXml && jackson2XmlPresent), then add MappingJackson2XmlHttpMessageConverter
            -> JSON 格式消息转换器配置
                -> if (jackson2Present), then add MappingJackson2HttpMessageConverterjackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
                -> else if (gsonPresent), then add GsonHttpMessageConverter
                -> else if (jsonbPresent), then add JsonbHttpMessageConverter
        -> 配置扩展 messageConvertersorg.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#extendMessageConverters
            -> for-each org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#delegates 调用 org.springframework.web.servlet.config.annotation.WebMvcConfigurer#extendMessageConverters
    -> 配置属性org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#setMessageConverters
-> 配置 WebBindingInitializer
    -> 获取 ConfigurableWebBindingInitializer调用 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration#getConfigurableWebBindingInitializer
        -> 通常无法获取有效 bean进入下一步的兜底逻辑调用 this.beanFactory.getBean(ConfigurableWebBindingInitializer.class)
        -> org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getConfigurableWebBindingInitializer
            -> new ConfigurableWebBindingInitializer
            -> 配置属性包括 ConversionServiceValidator
            -> org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#getMessageCodesResolver
                -> org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#getMessageCodesResolver
                    -> for-each org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#delegates, then org.springframework.web.servlet.config.annotation.WebMvcConfigurer#getMessageCodesResolver
                    -> 当前该方法返回 null
-> 配置 CustomArgumentResolvers
    -> org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getArgumentResolvers
        -> 此时 org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#argumentResolvers 为空
        -> org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#addArgumentResolvers
            -> org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#addArgumentResolvers
            -> 当前 this.delegates 的实现类均无有效逻辑
-> 配置 CustomReturnValueHandlers            
    -> org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getReturnValueHandlers
        -> 此时 org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#returnValueHandlers 为空
            -> org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#addReturnValueHandlers
            -> 当前 this.delegates 的实现类均无有效逻辑
-> if (jackson2Present)配置 JsonViewRequestBodyAdvice  JsonViewResponseBodyAdvice功能与注解 JsonView.class 有关
-> 配置 AsyncSupportConfigurer暂时略
    -> new AsyncSupportConfigurer
    -> org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#configureAsyncSupport
-> 配置 CallableInterceptors此时为空
-> 配置 DeferredResultInterceptor此时为空

分支 RequestMappingHandlerAdapter#afterPropertiesSet

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#afterPropertiesSet
-> 初始化 ControllerAdviceorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#initControllerAdviceCache
    -> 筛选 @ControllerAdvice 注解修饰的 bean将其封装为 ControllerAdviceBean list并排序org.springframework.web.method.ControllerAdviceBean#findAnnotatedBeans
        -> 筛选所有 benaBeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Object.class)
        -> 筛选 @ControllerAdvice 注解修饰的 beanbeanFactory.findAnnotationOnBean(name, ControllerAdvice.class)
        -> new ControllerAdviceBean
            -> 构造 HandlerTypePredicate用于后续判断 bean 是否符合条件例如通过 package 范围限定 ControllerAdvice 的作用范围
                -> 调用 org.springframework.web.method.ControllerAdviceBean#createBeanTypePredicate(org.springframework.web.bind.annotation.ControllerAdvice)
                -> if controllerAdvice != null从注解中解析 Predicate 信息
                -> else 先从 beanType 中查询 @ControllerAdvice 注解再从中解析 Predicate 信息
        -> 排序规则为 Order 通用规则OrderComparator.sort(adviceBeans)
    -> for-each adviceBeans
        -> 筛选同时被 @RequestMapping 注解和 @ModelAttribute 注解修饰的方法缓存到 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#modelAttributeAdviceCache
        -> 筛选被 @InitBinder 注解修饰的方法缓存到 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#initBinderAdviceCache
        -> 如果 beanType instanceof RequestBodyAdvice  beanType instanceof ResponseBodyAdvice缓存到 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#requestResponseBodyAdvice
            -> 此处解析的 RequestBodyAdvice/ResponseBodyAdvice 实现类的 bean 优先级高于其它方法配置的 bean因此调用 `this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);`。
-> 初始化默认 ArgumentResolvers org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#argumentResolvers
    -> 获取默认 ArgumentResolvers封装为 HandlerMethodArgumentResolver listorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultArgumentResolvers 
        -> 按类型排序的优先级降序为 Annotation-based argument resolutionType-based argument resolutionCustom argumentsCatch-all
        -> 常用处理器如下
            -> 处理 @RequestBody  @ResponseBody 注解修饰参数的方法参数处理器new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice))
            -> 处理 @RequestParam 注解修饰的参数及部分其它场景的方法参数处理器new RequestParamMethodArgumentResolver(getBeanFactory(), false)
                -> Supports the following:
                -> @RequestParam-annotated method arguments. This excludes Map params where the annotation does not specify a name. See RequestParamMapMethodArgumentResolver instead for such params.
                -> Arguments of type MultipartFile unless annotated with @RequestPart.
                -> Arguments of type Part unless annotated with @RequestPart.
                -> In default resolution mode, simple type arguments even if not with @RequestParam.
            -> 处理@PathVariable注解的方法参数处理器new PathVariableMethodArgumentResolver()
        -> 自定义处理器来源为 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#customArgumentResolvers
        -> 兜底处理器如下
            -> 支持范围是参数是简单类型如基本类型StringNumber等且无其他注解new RequestParamMethodArgumentResolver(getBeanFactory(), true))
            -> 其它略
    -> new HandlerMethodArgumentResolverComposite()
    -> org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#addResolvers(java.util.List<? extends org.springframework.web.method.support.HandlerMethodArgumentResolver>)
-> 初始化处理 @InitBinde 注解修饰的参数的默认 ArgumentResolvers org.springframework.web.servlet.mvc.method.annotation.
RequestMappingHandlerAdapter#initBinderArgumentResolvers
    -> 初始化处理 @InitBinde 注解修饰的参数的默认的参数处理器封装为 HandlerMethodArgumentResolver listorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultInitBinderArgumentResolvers
        -> 细节略详情参考 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultArgumentResolvers
    -> new HandlerMethodArgumentResolverComposite()
    -> org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#addResolvers(java.util.List<? extends org.springframework.web.method.support.HandlerMethodArgumentResolver>)
-> 初始化默认 ReturnValueHandler org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#returnValueHandlers
    -> 获取默认 MethodReturnValueHandler封装为 HandlerMethodReturnValueHandler listorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultReturnValueHandlers
        -> 按类型排序的优先级降序为 Single-purpose return value typesAnnotation-based return value typesType-based argument resolutionMulti-purpose return value typesCustom argumentsCatch-all
        -> 常用处理器如下
            -> 处理 HttpEntity  ResponseEntity 类型返回值也支持 HttpEntity  RequestEntity 类型参数new HttpEntityMethodProcessor(getMessageConverters(), this.contentNegotiationManager, this.requestResponseBodyAdvice))
            -> 处理 @ResponseBody 注解或 @RestController 注解也支持 @RequestBody 注解new RequestResponseBodyMethodProcessor(getMessageConverters(), this.contentNegotiationManager, this.requestResponseBodyAdvice))             
    -> new HandlerMethodReturnValueHandlerComposite()
    -> org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite#addHandlers

END