请求映射原理请求过来首先进入
javax.servlet.http.HttpServlet#doGet()-> org.springframework.web.servlet.FrameworkServlet#doGet()-> org.springframework.web.servlet.FrameworkServlet#processRequest()-> org.springframework.web.servlet.DispatcherServlet#doService()-> org.springframework.web.servlet.DispatcherServlet#doDispatch()->
protected void doDispatch(HttpServletRequest request, HttpServletResponse response)
throws Exception {
...
//找到当前请求使用哪个handler(controller的方法)处理
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
//为当前handler找到合适的handler适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
...
// 真正的调用
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
...
}
RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal()->
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
...
mav = invokeHandlerMethod(request, response, handlerMethod);
...
}
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod()->
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
...
//传参解析器
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
//返参处理器
if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
invocableMethod.invokeAndHandle(webRequest, mavContainer);
}
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle()->
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
...
}
org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest()
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//准备目标方法的参数值
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
...
return doInvoke(args);
}
?参数解析器HandlerMethodArgumentResolver 是为了确定将要执行的目标方法的每一个参数的值是什么。SpringMVC目标方法能写多少种参数类型,取决于参数解析器。
返回值处理器HandlerMethodReturnValueHandler 是为了封装返回数据的参数类型。
封装handler各参数值的主要逻辑
org.springframework.web.method.support.InvocableHandlerMethod#getMethodArgumentValues()
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
MethodParameter[] parameters = getMethodParameters();
if (ObjectUtils.isEmpty(parameters)) {
return EMPTY_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;
}
if (!this.resolvers.supportsParameter(parameter)) {
throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
}
try {
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;
}
|