-
判断每个参数带有注解是哪个,是否存在相应的解析器
-
寻找合适的处理适配器
DispatcherServlet中的
doDispatch方法
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
- 寻找可以处理相应注解的处理器
第一步
DispatcherServlet中的
doDispatch方法
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
第二步
RequestMappingHandlerAdapter中的
handleInternal方法
// No synchronization on session demanded at all...
mav = invokeHandlerMethod(request, response, handlerMethod);
invokeHandlerMethod方法
invocableMethod.invokeAndHandle(webRequest, mavContainer);
第三步
ServletInvocableHandlerMethod中的
invokeAndHandle方法
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
第四步
InvocableHandlerMethod类中的
invokeForRequest方法
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);//获取请求的参数
第五步
InvocableHandlerMethod类中的
getMethodArgumentValues方法
if (!this.resolvers.supportsParameter(parameter)) {//寻找处理相关注解的处理器,并保存到缓存中 supportsParameter(parameter)从这里进入的
throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
}
try {
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
}
第六步
HandlerMethodArgumentResolverComposite类中的
@Nullable
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result =
this.argumentResolverCache.get(parameter);//从缓存中获取,开始肯定没有
if (result == null) {
//增强for循环中选择合适的处理器 27个
for (HandlerMethodArgumentResolver resolver :
this.argumentResolvers) {
if (resolver.supportsParameter(parameter)) {
result = resolver;
//保存到缓存中
this.argumentResolverCache.put(parameter, result);
break;
}
}
}
return result;
}
- 通过注解处理器获取参数
第一步
InvocableHandlerMethod类中的
getMethodArgumentValues方法
try {
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); //真正开始获取参数
}
第二步
HandlerMethodArgumentResolverComposite类中的
resolveArgument方法中
//获取参数对应注解的处理器
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
getArgumentResolver方法中
//从缓存中获取,由于开始的之前往缓存中存入了,所以现在可以直接拿,如果没有下面还有可以循环寻找
HandlerMethodArgumentResolver result =
this.argumentResolverCache.get(parameter);
AbstractNamedValueMethodArgumentResolver类中的
resolveArgument方法
Object resolvedName =
resolveEmbeddedValuesAndExpressions(namedValueInfo.name);//获取参数名
Object arg = resolveName(resolvedName.toString(),
nestedParameter, webRequest);//获取参数值
//具体怎么获取
PathVariableMethodArgumentResolver类中的
resolveName方法
protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
Map uriTemplateVars = (Map) request.getAttribute(//直接从request请求域中获取
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
return (uriTemplateVars != null ? uriTemplateVars.get(name) : null);//在通过参数名称确定是哪一个
}
- 获取参数完成后,会调用InvocableHandlerMethod来中的doInvoke方法继续反射调用方法
InvocableHandlerMethod类中的
doInvoke方法
return method.invoke(getBean(), args);
Original: https://www.cnblogs.com/shuisanya/p/16630369.html
Author: 水三丫
Title: springBoot 获取注解参数的原理
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581448/
转载文章受原作者版权保护。转载请注明原作者出处!