SpringMVC之从ExceptionHandlerExceptionResolver源码解析之参数解析器和返回值处理器

一、ExceptionHandlerExceptionResolver

ExceptionHandlerExceptionResolver 的成员变量 :

  • 参数解析器 argumentResolvers,类型为 HandlerMethodArgumentResolverComposite
  • 返回值处理器 returnValueHandlers,类型为 HandlerMethodReturnValueHandlerComposite

两者都是在 afterPropertiesSet() 初始化的,源码如下:

1.1 getDefaultArgumentResolvers

分析参数解析器,就可以知道 @ExceptionHandler 注解的方法可以支持哪些参数,源码如下:

参数解析器 支持参数注解
SessionAttributeMethodArgumentResolver @SessionAttribute
RequestAttributeMethodArgumentResolver @RequestAttribute
参数解析器 支持并常用的参数类型
ServletRequestMethodArgumentResolver HttpServletRequest / InputStream / Reader ...
ServletResponseMethodArgumentResolver HttpServletResponse / OutputStream / Writer ...
RedirectAttributesMethodArgumentResolver RedirectAttributes 及其子类
ModelMethodProcessor Model 及其子类
PrincipalMethodArgumentResolver Principal 及其子类

1.2 getDefaultReturnValueHandlers

分析返回值处理器,就可以知道 @ExceptionHandler 注解的方法可以处理哪些类型的返回值,源码如下:

返回值处理器 支持返回值类型
ModelAndViewMethodReturnValueHandler ModelAndView 及其子类
Model Model 及其子类
ViewMethodReturnValueHandler View 及其子类
HttpEntityMethodProcessor HttpEntity 或者 RequestEntity
返回值处理器 支持返回值注解
ServletModelAttributeMethodProcessor @ModelAttribute
RequestResponseBodyMethodProcessor @RequestBody
返回处理器 返回值说明
ViewNameMethodReturnValueHandler 类似 "/page/user" 这样的字符串或者返回 void 时,直接解析类名为html页面文件名
MapMethodProcessor Map

二、自定义参数解析器/返回值处理器

WebMvcConfigurationSupport 中在注入 HandlerExceptionResolver Bean 时,会调用 addDefaultHandlerExceptionResolvers

2.1 getArgumentResolvers

WebMvcConfigurationSupportgetArgumentResolvers 源码如下,在 get 时会触发 addArgumentResolvers(List<HandlerMethodArgumentResolver>) 方法

DelegatingWebMvcConfigurationWebMvcConfigurationSupport 的子类,覆写了父类的 addArgumentResolvers(List<HandlerMethodArgumentResolver>) 方法:

DelegatingWebMvcConfiguration 会配置注入所有的 WebMvcConfigurer,并添加到成员变量 configurers 中:

configurers 的类型是 WebMvcConfigurerComposite,它的 addArgumentResolvers 源码如下:

也就是说,如果有个实现了 WebMvcConfigurer 接口的配置类,并且覆写 addArgumentResolvers 方法,就能配置自定义参数解析器了:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfiguration implements WebMvcConfigurer {
  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    // 添加 HandlerMethod 的自定义参数解析器
    argumentResolvers.add(...);
  }
}

2.2 getReturnValueHandlers

getReturnValueHandlersgetArgumentResolvers 的逻辑是类似的。

WebMvcConfigurationSupportgetReturnValueHandlers 源码如下,在 get 时会触发 addReturnValueHandlers(List<HandlerMethodReturnValueHandler>) 方法

DelegatingWebMvcConfigurationWebMvcConfigurationSupport 的子类,覆写了父类的 addReturnValueHandlers(List<HandlerMethodReturnValueHandler>) 方法:

configurers 的类型是 WebMvcConfigurerComposite,它的 addReturnValueHandlers 源码如下:

所以说,如果有个实现了 WebMvcConfigurer 接口的配置类,并且覆写 addReturnValueHandlers 方法,就能配置自定义返回值处理器了:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfiguration implements WebMvcConfigurer {
  public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
    // 添加 HandlerMethod 的自定义返回值处理器
    returnValueHandlers.add(...);
  }
}
posted @ 2022-03-17 14:52  极客子羽  阅读(430)  评论(0编辑  收藏  举报