在前一篇对DispatcherServlet的分析中,初略的过了下请求是如何处理的,本文将重点分析,HandlerMapping与HandlerAdapter是如何工作的
在web容器启动的过程中,会初初始化一系列SpringMVC所需的类,这里我们看看AbstractHandlerMethodMapping类的initHandlerMethods方法
如果bean中有相应注解 检测HandlerMethod
具体看看 selectMethods方法的实现
而其中的inspect方法 调用了 getMappingForMethod方法 具体实现 由其子类 RequestMappingHandlerMapping实现
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo info = createRequestMappingInfo(method);
if (info != null) {
RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
if (typeInfo != null) {
info = typeInfo.combine(info);
}
}
return info;
}
此方法返回的是一个RequestMappingInfo类实例,可见我们之前methods Map中的T 类型就为RequestMappingInfo
此类是一个封装了各种请求映射条件并实现了RequestCondition接口的类。有各种RequestCondition实现类属性,patternsCondition,methodsCondition,paramsCondition,headersCondition,consumesCondition以及producesCondition,这个请
求条件看属性名也了解,分别代表http请求的路径模式、方法、参数、头部等信息。
继续看getMappingForMethod方法,createRequestMappingInfo的具体实现如下:
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
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);
}
首先找到方法的@RequestMapping注解,然后获取RequestCondition ,如果有注解,则调用具体创建方法,否则返回null
protected RequestMappingInfo createRequestMappingInfo(
RequestMapping requestMapping, RequestCondition<?> customCondition) {
return RequestMappingInfo
.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
.methods(requestMapping.method())
.params(requestMapping.params())
.headers(requestMapping.headers())
.consumes(requestMapping.consumes())
.produces(requestMapping.produces())
.mappingName(requestMapping.name())
.customCondition(customCondition)
.options(this.config)
.build();
}
除了pathCondithion 其他都是直接使用 requestMapping注解中的condition
回头再看registerHandlerMethod方法