- HandlerMapping中找到能处理请求的Handler(Controller.method())
- 为当前Handler 找一个适配器 HandlerAdapter; RequestMappingHandlerAdapter
- 适配器执行目标方法并确定方法参数的每一个值
第一个:支持方法上标注的@RequestMapping
第二个:支持函数式编程
.....
2、执行目标方法 2.1 DispatcherServlet -- doDispatch// Actually invoke the handler. //DispatcherServlet -- doDispatch mv = ha.handle(processedRequest, response, mappedHandler.getHandler());2.2 RequestMappingHandlerAdapter--handleInternal
=====RequestMappingHandlerAdapter类中的handleInternal方法==========
mav = invokeHandlerMethod(request, response, handlerMethod); //执行目标方法
=====invokeHandlerMethod的关键代码===========================
if (this.argumentResolvers != null) {//设置参数解析器
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
if (this.returnValueHandlers != null) {//设置返回值处理器
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);
设置参数解析器:
参数解析器:确定将要执行的目标方法的每个参数的值是什么
SpringMVC目标方法能写多少种参数类型,取决于参数解析器。
supportParameter:当前解析器是否支持这种参数
支持就调用resolveArgument
设置返回值处理器:
2.3 invokeAndHandleinvocableMethod为ServletInvocableHandlerMethod对象
invokeForRequest:真正执行目标方法
=====ServletInvocableHandlerMethod中invokeAndHandle方法中的核心代码============== Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs); this.setResponseStatus(webRequest);2.4 invokeForRequest
=====invokeForRequest方法=====
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
//获取方法参数所有的值
Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
//反射执行Controller中的方法
return this.doInvoke(args);
}
2.5 getMethodArgumentValues:确定每个参数的值
上一步获取参数值的具体代码
============InvocableHandlerMethod类==========================
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
MethodParameter[] parameters = getMethodParameters();
if (ObjectUtils.isEmpty(parameters)) {
return EMPTY_ARGS;
}
//核心代码,args是最终确定好的值
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
args[i] = findProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
//1、遍历26个参数解析器是否支持parameter类型的参数
if (!this.resolvers.supportsParameter(parameter)) {
throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
}
try {
//2、开始解析参数值
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
}
catch (Exception ex) {
// Leave stack trace for later, exception may actually be resolved and handled...
if (logger.isDebugEnabled()) {
String exMsg = ex.getMessage();
if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
logger.debug(formatArgumentError(parameter, exMsg));
}
}
throw ex;
}
}
return args;
}
上图代码的细节:
2.5.1 判断所有参数解析器是否支持当前参数找到能解析的解析器,加入缓存,方便下一步解析该参数时直接获取。
======if (!this.resolvers.supportsParameter(parameter))底层实现=====
@Nullable
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) {
for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) {
if (resolver.supportsParameter(parameter)) {
result = resolver;
this.argumentResolverCache.put(parameter, result);
break;
}
}
}
return result;
}
2.5.2 解析参数的值
解析请求的值给到参数。
======args[i] = this.resolvers.resolveArgument======
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
HandlerMethodArgumentResolver resolver = this.getArgumentResolver(parameter);
if (resolver == null) {
throw new IllegalArgumentException("Unsupported parameter type [" + parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
} else {
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}
}
=====最终调用AbstractNamedValueMethodArgumentResolver的resolveArgument方法=====



