HandlerMapping HandlerAdapter

警告
本文最后更新于 2020-12-16,文中内容可能已过时。

spring源码系列文章,示例代码的中文注释,均是 copy 自 https://gitee.com/wlizhi/spring-framework

链接中源码是作者从 github 下载,并以自身理解对核心流程及主要节点做了详细的中文注释。


在@EnableWebMvc注解,激活mvc的一些组件时,其中就创建了 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter。

这两个类本身也是 InitializingBean 的实现,所以在创建后会调用 afterPropertiesSet() 初始化。

1 RequestMappingHandlerMapping 的初始化

RequestMappingHandlerMapping 主要封装 url、方法上的 @RequestMapping 注解信息、HandlerMethod、跨域配置等的一些映射关系,以及提供与此相关的一些操作方法。

1.1 主要流程

方法调用流程:

afterPropertiesSet() -> super.afterPropertiesSet() -> initHandlerMethods() -> processCandidateBean() -> detectHandlerMethods()

initHandlerMethods() 源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {

    protected void initHandlerMethods() {
		// 获取ApplicationContext容器中所有的beanName,循环判断不是以scopedTarget.开头的beanName执行候选操作。
		for (String beanName : getCandidateBeanNames()) {
			if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
				// TODO 执行操作。
				processCandidateBean(beanName);
			}
		}
		// 一个钩子方法,在查找并封装完完所有的处理方法各种映射关系之后,进行调用。
		handlerMethodsInitialized(getHandlerMethods());
	}
}

首先从容器中获取所有的 beanName 的数组。

遍历这些 beanName,将其作为参数依次调用 processCandidateBean()。

detectHandlerMethods() 源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {

    protected void detectHandlerMethods(Object handler) {
		Class<?> handlerType = (handler instanceof String ?
				obtainApplicationContext().getType((String) handler) : handler.getClass());

		if (handlerType != null) {
			Class<?> userType = ClassUtils.getUserClass(handlerType);
			// 获取方法 - RequestMappingInfo 的映射
			Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
					(MethodIntrospector.MetadataLookup<T>) method -> {
						try {
							// 根据类和方法上RequestMapping中的value,结合成一个路径封装成RequestMappingInfo返回
							return getMappingForMethod(method, userType);
						}
						catch (Throwable ex) {
							throw new IllegalStateException("Invalid mapping on handler class [" +
									userType.getName() + "]: " + method, ex);
						}
					});
			if (logger.isTraceEnabled()) {
				logger.trace(formatMappings(userType, methods));
			}
			// TODO 注册处理方法
			methods.forEach((method, mapping) -> {
				// 获取到可调用的方法
				Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
				// TODO 注册 HandlerMethod
				registerHandlerMethod(handler, invocableMethod, mapping);
			});
		}
	}
}
  1. 遍历类中所有方法,获取 Method - RequestMappingInfo 的映射关系。
  2. 注册 HandlerMethod。

1.2 获取 Method-RequestMappingInfo 映射

selectMethods() 源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public final class MethodIntrospector {

	public static <T> Map<Method, T> selectMethods(Class<?> targetType, final MetadataLookup<T> metadataLookup) {
		final Map<Method, T> methodMap = new LinkedHashMap<>();
		Set<Class<?>> handlerTypes = new LinkedHashSet<>();
		Class<?> specificHandlerType = null;

		if (!Proxy.isProxyClass(targetType)) {
			specificHandlerType = ClassUtils.getUserClass(targetType);
			handlerTypes.add(specificHandlerType);
		}
		// 获取类实现的所有接口
		handlerTypes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetType));

		for (Class<?> currentHandlerType : handlerTypes) {
			final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);

			ReflectionUtils.doWithMethods(currentHandlerType, method -> {
				Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
				T result = metadataLookup.inspect(specificMethod);
				if (result != null) {
					Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
					// inspect() 调用到了外层的匿名对象
					if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) {
						// 方法-RequestMappingInfo映射
						methodMap.put(specificMethod, result);
					}
				}
			}, ReflectionUtils.USER_DECLARED_METHODS);
		}

		return methodMap;
	}
}
  1. 遍历本类以及所有实现接口的 Class 对象。
  2. 获取到该 Class 中定义的所有方法、遍历。
  3. 调用外层匿名对象中的 inspect 方法,获取到 result,即会调用到 getMappingForMethod(),最终获取到 RequestMappingInfo 实例。
  4. 将当前方法与获取到的 RequestMappingInfo,建立映射管理,存储到一个 map 集合中。

getMappingForMethod() 中,调用了 createRequestMappingInfo(),源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
		implements MatchableHandlerMapping, EmbeddedValueResolverAware {
    // 步骤 1
    protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
		RequestMappingInfo info = createRequestMappingInfo(method);
		if (info != null) {
			// TODO 创建 RequestMappingInfo,这里完成了 @RequestMappingInfo 的扫描及封装操作。
			RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
			if (typeInfo != null) {
				// 将类上的 @RequestMappingInfo 和方法上的 @RequestMappingInfo 结合。
				info = typeInfo.combine(info);
			}
			String prefix = getPathPrefix(handlerType);
			if (prefix != null) {
				info = RequestMappingInfo.paths(prefix).build().combine(info);
			}
		}
		return info;
	}

    // 步骤 2
	private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
		// 扫描 @RequestMapping 注解,将必要的信息封装成 RequestMappingInfo
		RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
		RequestCondition<?> condition = (element instanceof Class ?
				getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
		return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
	}

    // 步骤 3
    protected RequestMappingInfo createRequestMappingInfo(
			RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {
		// 这里面封装了方法上 @RequestMapping 注解的一些参数值。
		RequestMappingInfo.Builder builder = RequestMappingInfo
				.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
				.methods(requestMapping.method())
				.params(requestMapping.params())
				.headers(requestMapping.headers())
				.consumes(requestMapping.consumes())
				.produces(requestMapping.produces())
				.mappingName(requestMapping.name());
		if (customCondition != null) {
			builder.customCondition(customCondition);
		}
		return builder.options(this.config).build();
	}

}

如果方法上有注解 @RequestMapping,则封装成 RequestMappingInfo。内部封装了方法、以及 @RequestMapping 中设置的一系列参数值。

1.3 注册 HandlerMethod

在获取到 方法 - RequestMappingInfo 映射关系后,循环这个map,依次对其进行注册。

源码如下:

1
2
3
4
5
6
7
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {

	protected void registerHandlerMethod(Object handler, Method method, T mapping) {
		// TODO 注册映射信息
		this.mappingRegistry.register(mapping, handler, method);
	}
}

register() 源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {

    public void register(T mapping, Object handler, Method method) {
        this.readWriteLock.writeLock().lock();
        try {
            // 封装HanlderMethod
            HandlerMethod handlerMethod = createHandlerMethod(handler, method);
            assertUniqueMethodMapping(handlerMethod, mapping);
            // TODO 封装 RequestMappingInfo - HandlerMethod 映射关系
            this.mappingLookup.put(mapping, handlerMethod);
            // url - mapping 映射关系,mapping-handlerMethod的映射关系。这两个map很重要。请求url匹配到处理方法,就是通过这两个关系映射来匹配的。
            // TODO 获取到RequestMappingInfo中的 paths(用于匹配请求路径的url),遍历,依次建立 url - RequestMappingInfo的映射关系。
            List<String> directUrls = getDirectUrls(mapping);
            for (String url : directUrls) {
                // 建立 url - RequestMappingInfo的映射关系。
                // 当一个请求过来的时候,就可以根据url找到对应的RequestMappingInfo,通过RequestMappingInfo
                // 就可以在 mappingLookup 中找到 handlerMethod,即controller中的方法。
                this.urlLookup.add(url, mapping);
            }

            // requestMappingInfo的名称策略,将名称 - requestMappingInfo的映射缓存到 nameLookup。
            String name = null;
            if (getNamingStrategy() != null) {
                name = getNamingStrategy().getName(handlerMethod, mapping);
                addMappingName(name, handlerMethod);
            }
            // 缓存跨域配置信息。将handlerMethod和corsConfig的映射缓存到 corsLookup
            CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
            if (corsConfig != null) {
                this.corsLookup.put(handlerMethod, corsConfig);
            }
            // RequestMappingInfo - MappingRegistration映射。
            // MappingRegistration 中封装了 RequestMappingInfo、HandlerMethod、directUrls、mappingName信息。
            this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));
        }
        finally {
            this.readWriteLock.writeLock().unlock();
        }
    }
}

方法流程:

  1. 创建 HandlerMethod。
  2. 将 RequestMappingInfo - HandlerMethod 的映射关系存储到 mappingLookup。
  3. 查找到 RequestMappingInfo 中所有的 url信息。
  4. 将 url - RequestMappingInfo 的映射关系,存储到 urlLookup。
  5. 初始化跨域相关配置信息,将 HandlerMethod - corsConfig 映射关系存储到 corsLookup。
  6. 将 RequestMappingInfo、HandlerMethod、directUrls、mappingName 信息封装到 MappingRegistration,并以 RequestMappingInfo 作为键值,缓存到变量 registry。

mappingRegistry 是 RequestMappingHandlerMapping 中的一个成员变量,最终,上面流程获取到的信息都会注册到这里。

它的声明如下:

1
2
3
4
5
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {

	/** 注册mapping,这里面封装了一系列的映射信息,url-requestMappingInfo、requestMappingInfo-handlerMethod等的映射。 */
	private final MappingRegistry mappingRegistry = new MappingRegistry();
}

MappingRegistry 的数据结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class MappingRegistry {
    /** 封装了 RequestMappingInfo、HandlerMethod、directUrls、mappingName信息。 */
    private final Map<T, MappingRegistration<T>> registry = new HashMap<>();
    /** 封装 RequestMappingInfo - HandlerMethod 映射关系 */
    private final Map<T, HandlerMethod> mappingLookup = new LinkedHashMap<>();
    /** 封装 url - RequestMappingInfo 映射信息 */
    private final MultiValueMap<String, T> urlLookup = new LinkedMultiValueMap<>();
    /** 封装 RequestMappingInfo名称 - HandlerMethod列表 映射信息 */
    private final Map<String, List<HandlerMethod>> nameLookup = new ConcurrentHashMap<>();
    /** 封装 handlerMethod - cors跨域配置的映射信息 */
    private final Map<HandlerMethod, CorsConfiguration> corsLookup = new ConcurrentHashMap<>();
    /** 读写锁,保证线程安全,在写入的时候不允许读写,读操作可以并行执行 */
    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
}

封装了许多的有关 url、RequestMappingInfo、HandlerMethod、cors配置等的映射关系,以map的方式存储到成员变量中。

HandlerMethod 的构造及数据结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class HandlerMethod {
	/** Logger that is available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());
	/** bean实例 */
	private final Object bean;
	/** beanFactory 工厂 */
	@Nullable
	private final BeanFactory beanFactory;
	/** bean的类型 */
	private final Class<?> beanType;
	/** 方法 */
	private final Method method;
	/** 桥接方法 */
	private final Method bridgedMethod;
	/** 方法参数封装 */
	private final MethodParameter[] parameters;
	// 省略其他变量...

	public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) {
	    // 省略无关代码...
		// 这里的变量 bean,仅仅封装了一个 beanName,并没有设置具体的实例。这个实例会在第一次调用controller方法时,去设置。
		this.bean = beanName;
		this.beanFactory = beanFactory;
		Class<?> beanType = beanFactory.getType(beanName);
		if (beanType == null) {
			throw new IllegalStateException("Cannot resolve bean type for bean with name '" + beanName + "'");
		}
		// 这里仅仅设置了一个beanType,这时候,bean实例并没有封装进来。在真正调用方法执行时,这个bean实例是必须有的。
		// 它在别的地方进行了设置。
		this.beanType = ClassUtils.getUserClass(beanType);
		this.method = method;
		this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
		this.parameters = initMethodParameters();
		evaluateResponseStatus();
	}
}

注意这里的变量 this.bean 保存的是 beanName,而非 bean 的实例。

在构造 HandlerMethod 时,仅仅把 beanName 和 beanClass 设置到成员变量保存起来,在这里并没有获取 bean 的具体实例,这个实例实际上是在第一次调用的时候,通过 beanFactory.getBean() 获取的,获取后,将 this.bean 的值替换为了具体的实例。这也是懒加载的一种体现。

2 RequestMappingHandlerAdapter 的初始化

2.1 数据结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
		implements BeanFactoryAware, InitializingBean {
	
	public static final MethodFilter INIT_BINDER_METHODS = method ->
			AnnotatedElementUtils.hasAnnotation(method, InitBinder.class);

	public static final MethodFilter MODEL_ATTRIBUTE_METHODS = method ->
			(!AnnotatedElementUtils.hasAnnotation(method, RequestMapping.class) &&
					AnnotatedElementUtils.hasAnnotation(method, ModelAttribute.class));

	/** 自定义的参数解析器,策略模式的运用, HandlerMethodArgumentResolver中提供了两个方法:是否支持解析参数的判断、解析参数方法。*/
	@Nullable
	private List<HandlerMethodArgumentResolver> customArgumentResolvers;
	/** 参数解析聚合,内部封装了所有的HandlerMethodArgumentResolver实例 */
	@Nullable
	private HandlerMethodArgumentResolverComposite argumentResolvers;
	/** initBinder参数解析器 */
	@Nullable
	private HandlerMethodArgumentResolverComposite initBinderArgumentResolvers;
	/** 自定义的返回值处理器 */
	@Nullable
	private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;
	/** 返回值处理组合,与WebMvcConfigurer组合类设计模式相同。内部封装了所有的HandlerMethodReturnValueHandler */
	@Nullable
	private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
	/** 视图解析器 */
	@Nullable
	private List<ModelAndViewResolver> modelAndViewResolvers;

	private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
	/** 消息转换器 */
	private List<HttpMessageConverter<?>> messageConverters;
	/** 一些增强类,参数解析、返回值处理类的封装 */
	private List<Object> requestResponseBodyAdvice = new ArrayList<>();
    // 省略其他变量...
}

RequestMappingHandlerAdapter 封装了许多的策略处理,包括 方法参数解析、返回值处理、消息转换器等等。每一种都包含许多的方式去处理,有太多可能情况,所以使用策略模式。

无论是 参数解析、返回值、消息转换都有很多种可能,比如 post表单提交的参数、以流的方式传递的 json 参数,等等。每一种都对应的有相应的处理实现类。

2.2 主流程

首先会调用初始化方法 afterPropertiesSet(),源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
		implements BeanFactoryAware, InitializingBean {
	public void afterPropertiesSet() {
		// TODO 在第一次执行时,会初始化ControllerAdvice缓存。
		// Do this first, it may add ResponseBody advice beans
		initControllerAdviceCache();

		if (this.argumentResolvers == null) {
			// TODO 参数解析器,里面注册了很多的参数解析类。实际上,参数的解析是一个十分复杂的过程,它的可能情况太多了。
			List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
			// 将所有的参数解析器封装到 argumentResolvers 中。
			this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
		if (this.initBinderArgumentResolvers == null) {
			// initBinder 参数解析器
			List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
			this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
		if (this.returnValueHandlers == null) {
			// 方法返回值处理类注册
			List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
			this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
		}
	}
}
  1. 首先缓存异常处理相关类。
  2. 注册默认的参数解析器设置。这里会注册一系列的参数解析器。
  3. 注册 initBinder 参数解析器。同上。
  4. 注册默认的方法返回值处理类。同上。

2.3 初始化 ControllerAdvice 缓存

源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
		implements BeanFactoryAware, InitializingBean {
	private void initControllerAdviceCache() {
		if (getApplicationContext() == null) {
			return;
		}
		// TODO 全局异常处理的Bean扫描,@ControllerAdvice 注解的bean会被扫描到。
		List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
		AnnotationAwareOrderComparator.sort(adviceBeans);

		List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();

		for (ControllerAdviceBean adviceBean : adviceBeans) {
			Class<?> beanType = adviceBean.getBeanType();
			if (beanType == null) {
				throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
			}
			// 方法过滤器 @RequestMapping && @ModelAttribute 注解扫描
			Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
			if (!attrMethods.isEmpty()) {
				// 封装adviceBean和 @ModelAttribute 注解方法的映射关系。
				this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
			}
			// 方法过滤器 InitBinder 扫描
			Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
			if (!binderMethods.isEmpty()) {
				// 封装 adviceBean 和 binderMethods 的映射关系
				this.initBinderAdviceCache.put(adviceBean, binderMethods);
			}
			if (RequestBodyAdvice.class.isAssignableFrom(beanType)) {
				requestResponseBodyAdviceBeans.add(adviceBean);
			}
			if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
				requestResponseBodyAdviceBeans.add(adviceBean);
			}
		}

		if (!requestResponseBodyAdviceBeans.isEmpty()) {
			this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
		}
		// 省略无关代码...
	}
}

这里重点在注解扫描,源码如下:

1
2
3
4
5
6
7
8
9
public class ControllerAdviceBean implements Ordered {
    public static List<ControllerAdviceBean> findAnnotatedBeans(ApplicationContext context) {
		// 这里是针对Controller层全局异常处理注解支持的扫描。
		return Arrays.stream(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, Object.class))
				.filter(name -> context.findAnnotationOnBean(name, ControllerAdvice.class) != null)
				.map(name -> new ControllerAdviceBean(name, context))
				.collect(Collectors.toList());
	}
}

上面流程中,扫描了容器中所有带有 @ControllerAdvice 注解的 beanName,并封装为 ControllerAdviceBean。ControllerAdviceBean 中封装了 bean实例(刚开始是beanName)、排序、@ControllerAdvice注解信息。

ControllerAdviceBean 数据结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class ControllerAdviceBean implements Ordered {
	/** bean实例 */
	private final Object bean;
	/** beanFactory */
	private final BeanFactory beanFactory;
	/** 排序,通过@Order注解来设置 */
	private final int order;
	/** ControllerAdvice 注解中的参数信息封装 */
	private final HandlerTypePredicate beanTypePredicate;
}

2.4 注册默认参数解析器

getDefaultArgumentResolvers() 源码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
		implements BeanFactoryAware, InitializingBean {
    private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
		List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
		// 这里注册了一系列的默认参数解析器,在大多数应用场景下的参数解析,都是可以支持的,一般不需要我们自定义。
		// 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 ServletModelAttributeMethodProcessor(false));
		resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
		resolvers.add(new RequestHeaderMapMethodArgumentResolver());
		resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
		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());
		resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RedirectAttributesMethodArgumentResolver());
		resolvers.add(new ModelMethodProcessor());
		resolvers.add(new MapMethodProcessor());
		resolvers.add(new ErrorsMethodArgumentResolver());
		resolvers.add(new SessionStatusMethodArgumentResolver());
		resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

		// Custom arguments
		if (getCustomArgumentResolvers() != null) {
			resolvers.addAll(getCustomArgumentResolvers());
		}

		// Catch-all
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
		resolvers.add(new ServletModelAttributeMethodProcessor(true));

		return resolvers;
	}
}

注册了许多的参数解析器,实际上,参数的解析十分复杂。

从类名称上大致可以推断出它的作用。

比如 PathVariableMethodArgumentResolver 就是处理 url 中使用占位符接收参数。RequestParamMethodArgumentResolver 处理表单提交的参数。RequestResponseBodyMethodProcessor 处理json参数等。

2.5 注册默认返回值处理类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
		implements BeanFactoryAware, InitializingBean {
    private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
		List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();
		// 注册了很多返回值处理类,用于处理返回值的一些信息。
		// Single-purpose return value types
		handlers.add(new ModelAndViewMethodReturnValueHandler());
		handlers.add(new ModelMethodProcessor());
		handlers.add(new ViewMethodReturnValueHandler());
		handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),
				this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
		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));
		handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
				this.contentNegotiationManager, this.requestResponseBodyAdvice));

		// Multi-purpose return value types
		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;
	}
}

如上源码,返回值的处理类也有很多。

其他的一些策略类的注册,与上面流程类似。