您的位置:首页 > 移动开发

SpringMVC之分析RequestMappingHandlerAdapter(二)

2017-10-28 16:33 621 查看
接上篇文章,我们在这一篇文章中继续对RequestMappingHandlerAdapter这个类进行分析。在上篇文章中我们说到afterPropertiesSet这个方法中添加的一些MethodHandlerResolver,我们继续分析这个方法中的其他代码:

if (this.initBinderArgumentResolvers == null) {
List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
在我们做表单提交的时候可能需要对一些特殊值进行转换,比如时间格式,金钱等,这个时候我们可能会用到InitBinder这个注解,来添加一些特殊的编辑器。上面这几段代码的意思是,需要对哪些类型的请求映射处理方法的参数注册一些特殊的编辑器。如果我们没有配置过initBinderArgumentResolvers 这个属性的值的话,那么它会去getDefaultInitBinderArgumentResolvers这个方法中默认的一些参数解析器。如下所示:

private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
// Annotation-based argument resolution
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
resolvers.add(new RequestParamMapMethodArgumentResolver());
resolvers.add(new PathVariableMethodArgumentResolver());
resolvers.add(new PathVariableMapMethodArgumentResolver());
resolvers.add(new MatrixVariableMethodArgumentResolver());
resolvers.add(new MatrixVariableMapMethodArgumentResolver());
resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
resolvers.add(new SessionAttributeMethodArgumentResolver());
resolvers.add(new RequestAttributeMethodArgumentResolver());
// Type-based argument resolution
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
//自定义的参数解析器
// Custom arguments
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
return resolvers;
}
自定义的参数解析器,也会被添加到这个集合中,initBinderArgumentResolvers 这个类也是为托给HandlerMethodArgumentResolverComposite这个类来处理的。如果我们设置了initBinderArgumentResolvers 的话,那么它只会取我们设置的参数解析器。

下面我们再看一下returnValueHandlers返回值的处理器。我们在做项目的时候,有时候返回的是一个页面,有时候返回的是一个字符串,有时候返回的是JSON对象(静态资源除外),这些不同的返回值的处理是通过一些HandlerMethodReturnValueHandler的实现类来做的,这个我们以后会找几个常用的HandlerMethodReturnValueHandler实现类来分析一下,SpringMVC大概给我们默认了这么多的返回值处理器:

if (this.returnValueHandlers == null) {
List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
SpringMVC默认的returnValueHandler

private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>();

// Single-purpose return value types
//返回一个ModelAndView
handlers.add(new ModelAndViewMethodReturnValueHandler());
handlers.add(new ModelMethodProcessor());
handlers.add(new ViewMethodReturnValueHandler());
handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters()));
handlers.add(new StreamingResponseBodyReturnValueHandler());
handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
handlers.add(new HttpHeadersReturnValueHandler());
handlers.add(new CallableMethodReturnValueHandler());
handlers.add(new DeferredResultMethodReturnValueHandler());
handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));
// Annotation-based return value types
handlers.add(new ModelAttributeMethodProcessor(false));
//有RequestBody和ResponseBody注解的方法
handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
// Multi-purpose return value types
//直接返回一个字符,注意这个字符串是不带ResponseBody注解的
handlers.add(new ViewNameMethodReturnValueHandler());
handlers.add(new MapMethodProcessor());
// Custom return value types
//自定义的返回值处理器
if (getCustomReturnValueHandlers() != null) {
handlers.addAll(getCustomReturnValueHandlers());
}
// Catch-all
if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
}
else {
handlers.add(new ModelAttributeMethodProcessor(true));
}

return handlers;
}

这个returnValueHandlers 是HandlerMethodReturnValueHandlerComposite这个对象的实例。

在上面的分析中有一点需要我们注意的是,我们将HandlerMethodArgumentResolver、HandlerMethodReturnValueHandler、HttpMessageConverter等放到了相应的集合中,这个放入的顺序是很重要的。

我们在做SpringMVC开发的时候,只需要在SpringMVC的配置文件中添加这么一句话 <mvc:annotation-driven/>,就可以进行正常的Web开发的工作。那么RequestMappingHandlerAdapter、RequestMappingHandlerMapping等这些类是什么时候注入到Spring的Bean容器的呢?我们在下一篇的文章中会进行说明。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息