接上篇文章,我们在这一篇文章中继续对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容器的呢?我们在下一篇的文章中会进行说明。