SpringMVC之分析RequestMappingHandlerAdapter(二)

简介: 接上篇文章,我们在这一篇文章中继续对RequestMappingHandlerAdapter这个类进行分析。在上篇文章中我们说到afterPropertiesSet这个方法中添加的一些MethodHandlerResolver,我们继续分析这个方法中的其他代码: if (this.

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


相关文章
|
Java Spring
享读SpringMVC源码4-感谢RequestMappingHandlerAdapter(下)
享读SpringMVC源码4-感谢RequestMappingHandlerAdapter(下)
享读SpringMVC源码4-感谢RequestMappingHandlerAdapter(下)
|
数据采集 缓存 Java
享读SpringMVC源码4-感谢RequestMappingHandlerAdapter(上)
享读SpringMVC源码4-感谢RequestMappingHandlerAdapter(上)
|
缓存 Java API
SpringMVC源码解析之RequestMappingHandlerAdapter(上))
SpringMVC源码解析之RequestMappingHandlerAdapter(上))
210 0
SpringMVC源码解析之RequestMappingHandlerAdapter(上))
|
前端开发 Java Spring
SpringMVC源码解析之RequestMappingHandlerAdapter(下)
SpringMVC源码解析之RequestMappingHandlerAdapter(下)
184 0
|
Java Spring uml
SpringMVC之分析RequestMappingHandlerAdapter(一)
RequestMappingHandlerAdapter请求映射处理适配器,在SpringMVC中它是一个非常重要的类,对请求处理方法的调用主要是通过这个类来完成的(这段代码mv = ha.handle(processedRequest, response, mappedHandler.getHandler());)。
1397 0
|
6月前
|
设计模式 前端开发 JavaScript
Spring MVC(一)【什么是Spring MVC】
Spring MVC(一)【什么是Spring MVC】
|
5月前
|
设计模式 前端开发 Java
【Spring MVC】快速学习使用Spring MVC的注解及三层架构
【Spring MVC】快速学习使用Spring MVC的注解及三层架构
76 1
|
5月前
|
前端开发 Java 应用服务中间件
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
|
6月前
|
前端开发 Java 关系型数据库
基于ssm框架旅游网旅游社交平台前后台管理系统(spring+springmvc+mybatis+maven+tomcat+html)
基于ssm框架旅游网旅游社交平台前后台管理系统(spring+springmvc+mybatis+maven+tomcat+html)
|
5月前
|
XML Java 数据格式
SpringMVC的XML配置解析-spring18
SpringMVC的XML配置解析-spring18