以一个简单请求为例进行说明:
@RestController public class DemoController { @GetMapping("hello") public String sayHello() { return "hello world"; } }
首先列一下doDispatch方法进行说明:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; Exception dispatchException = null; try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // Determine handler for the current request.根据请求的url获取处理请求的controller和controller中的方法。 mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request.根据处理器的类型获取处理器的适配器,使用适配器通过反射进行真正的方法调用。 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler.适配器处理请求(通过反射调用controller中的方法)。 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { // As of 4.3, we're processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException("Handler dispatch failed", err); } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", err)); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } } }
下面打断点一步步跟一下:
1-获取mappedHandler = getHandler(processedRequest); 获取处理请求的controller信息和方法信息。
2-HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());根据处理器获取适配器,从断点看适配器类型为:RequestMappingHandlerAdapter。
3-mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 真正调用处理方法。
AbstractHandlerMethodAdapter.class(RequestMappingHandlerAdapter的父类)
@Override
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler); }
RequestMappingHandlerAdapter.class
@Override protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ModelAndView mav;
...... // No synchronization on session demanded at all... 调用此方法继续执行 mav = invokeHandlerMethod(request, response, handlerMethod); ...... return mav; }
@Nullable protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ...... //调用此方法继续执行 invocableMethod.invokeAndHandle(webRequest, mavContainer);
...... }
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { //调用此方法继续执行 Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); }
InvocableHandlerMethod.class
@Nullable public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs); if (this.logger.isTraceEnabled()) { this.logger.trace("Arguments: " + Arrays.toString(args)); } //调用此方法 return this.doInvoke(args); }
@Nullable protected Object doInvoke(Object... args) throws Exception { ReflectionUtils.makeAccessible(this.getBridgedMethod()); ......
//反射执行controller中的处理方法 return this.getBridgedMethod().invoke(this.getBean(), args);
......
}
调试获取this.getBridgedMethod(),Method为controller中的sayHello()处理方法:
调试获取this.getBean()为DemoCOntroller的一个对象:
即最后通过Method.class的public Object invoke(Object obj, Object... args)方法去完成DemoController中sayHello()方法的调用。