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
WebMvcConfigurationSupport 的 getArgumentResolvers 源码如下,在 get 时会触发 addArgumentResolvers(List<HandlerMethodArgumentResolver>) 方法
DelegatingWebMvcConfiguration 是 WebMvcConfigurationSupport 的子类,覆写了父类的 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
getReturnValueHandlers 跟 getArgumentResolvers 的逻辑是类似的。
WebMvcConfigurationSupport 的 getReturnValueHandlers 源码如下,在 get 时会触发 addReturnValueHandlers(List<HandlerMethodReturnValueHandler>) 方法
DelegatingWebMvcConfiguration 是 WebMvcConfigurationSupport 的子类,覆写了父类的 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(...);
}
}