1.RequestMappingHandlerMapping继承图
2.概述
通过加controller注解或requestmapping的类来作为处理器,每次请求都会到加了requestmapping的方法
3.RequestMappingHandlerMapping源码翻译后的
https://blog.csdn.net/qq_39482039/article/details/119765441
4.初始化流程
AbstractHandlerMethodMapping实现了InitializingBean接口,默认bean初始化会调用afterPropertiesSet方法,RequestMappingHandlerMapping重写了afterPropertiesSet方法
@Override
public void afterPropertiesSet() {
//初始化一些配置信息
this.config = new RequestMappingInfo.BuilderConfiguration();
this.config.setUrlPathHelper(getUrlPathHelper());
this.config.setPathMatcher(getPathMatcher());
this.config.setSuffixPatternMatch(this.useSuffixPatternMatch);
this.config.setTrailingSlashMatch(this.useTrailingSlashMatch);
this.config.setRegisteredSuffixPatternMatch(this.useRegisteredSuffixPatternMatch);
this.config.setContentNegotiationManager(getContentNegotiationManager());
//调用父类的方法
super.afterPropertiesSet();
}
关键方法isHandler方法,RequestMappingHandlerMapping重写了AbstractHandlerMethodMapping中isHandler方法,AbstractHandlerMethodMapping初始化获取了所有的bean,哪些bean才是处理器是通过这个方法判断的,类上有controller或requestmapping的注解表示当前是一个处理器
/**
* {@inheritDoc}
* <p>期望处理程序具有类型级别的@{@link Controller}
* 注释或类型级别的 @{@link RequestMapping} 注释。
*/
@Override
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
getMappingForMethod方法,在AbstractHandlerMethodMapping中detectHandlerMethods方法中调用,根据处理器和方法创建RequestMappingInfo
/**
* 使用方法和类型级别的@{@link RequestMapping}批注创建* RequestMappingInfo。
*
* @return the created RequestMappingInfo, or {@code null} if the method
* does not have a {@code @RequestMapping} annotation.
* @see #getCustomMethodCondition(Method)
* @see #getCustomTypeCondition(Class)
*/
@Override
@Nullable
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
//根据当前方法创建RequestMappingInfo实例
RequestMappingInfo info = createRequestMappingInfo(method);
if (info != null) {
RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
if (typeInfo != null) {
info = typeInfo.combine(info);
}
String prefix = getPathPrefix(handlerType);
if (prefix != null) {
info = RequestMappingInfo.paths(prefix).build().combine(info);
}
}
return info;
}
查找方法上的requestmapping注解,创建requestmappinginfo
/**
* 委托给 {@link #createRequestMappingInfo(RequestMapping, RequestCondition)},
* 根据是否提供适当的自定义 {@link RequestCondition}
* 提供的 {@code annotatedElement} 是一个类或方法。
*
* @see #getCustomTypeCondition(Class)
* @see #getCustomMethodCondition(Method)
*/
@Nullable
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);
}
/**
* 从提供的创建 {@link RequestMappingInfo}
* {@link RequestMapping @RequestMapping} 注解,可以是
* 直接声明的注解、元注解或合成的
* 在注释层次结构中合并注释属性的结果。
*/
protected RequestMappingInfo createRequestMappingInfo(
RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {
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();
}
重写AbstractHandlerMethodMapping的将处理程序注册的方法
@Override
protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
super.registerHandlerMethod(handler, method, mapping);
updateConsumesCondition(mapping, method);
}
private void updateConsumesCondition(RequestMappingInfo info, Method method) {
ConsumesRequestCondition condition = info.getConsumesCondition();
if (!condition.isEmpty()) {
for (Parameter parameter : method.getParameters()) {
MergedAnnotation<RequestBody> annot = MergedAnnotations.from(parameter).get(RequestBody.class);
if (annot.isPresent()) {
condition.setBodyRequired(annot.getBoolean("required"));
break;
}
}
}
}