spring mvc代码分析
我们都知道,spring mvc 的入口就在于 DispatcherServlet,那里面应该就有个 doDispatch 的方法
核心代码如下:
mappedHandler = this.getHandler(processedRequest);// 获取Handler HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());// 获取HandlerAdapter mv = ha.handle(processedRequest, response, mappedHandler.getHandler());// HandlerAdapter 处理,返回 ModelAndView
调用 AbstractHandlerMethodAdapter 中的如下方法:
@Nullable public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return this.handleInternal(request, response, (HandlerMethod)handler); }
我们看到又调用了 handleInternal ,这是个抽象方法,会根据对应的Adapter 实现来调用。这里会调用RequestMappingHandlerAdapter#handleInternal
实现如下:
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { this.checkRequest(request); ModelAndView mav; if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized(mutex) { mav = this.invokeHandlerMethod(request, response, handlerMethod); } } else { mav = this.invokeHandlerMethod(request, response, handlerMethod); } } else { mav = this.invokeHandlerMethod(request, response, handlerMethod); } if (!response.containsHeader("Cache-Control")) { if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else { this.prepareResponse(response); } } return mav; }
然后调用 invokeHandlerMethod 返回 ModelAndView,最终调用的是ServletInvocableHandlerMethod#invokeAndHandle
代码如下:
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs); this.setResponseStatus(webRequest); if (returnValue == null) { if (this.isRequestNotModified(webRequest) || this.getResponseStatus() != null || mavContainer.isRequestHandled()) { this.disableContentCachingIfNecessary(webRequest); mavContainer.setRequestHandled(true); return; } } else if (StringUtils.hasText(this.getResponseStatusReason())) { mavContainer.setRequestHandled(true); return; } mavContainer.setRequestHandled(false); Assert.state(this.returnValueHandlers != null, "No return value handlers"); try { this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest); } catch (Exception var6) { if (this.logger.isTraceEnabled()) { this.logger.trace(this.formatErrorForReturnValue(returnValue), var6); } throw var6; } }
然后执行InvocableHandlerMethod#invokeForRequest
@Nullable protected Object doInvoke(Object... args) throws Exception { ReflectionUtils.makeAccessible(this.getBridgedMethod()); try { return this.getBridgedMethod().invoke(this.getBean(), args); } catch (IllegalArgumentException var4) { this.assertTargetBean(this.getBridgedMethod(), this.getBean(), args); String text = var4.getMessage() != null ? var4.getMessage() : "Illegal argument"; throw new IllegalStateException(this.formatInvokeError(text, args), var4); } catch (InvocationTargetException var5) { Throwable targetException = var5.getTargetException(); if (targetException instanceof RuntimeException) { throw (RuntimeException)targetException; } else if (targetException instanceof Error) { throw (Error)targetException; } else if (targetException instanceof Exception) { throw (Exception)targetException; } else { throw new IllegalStateException(this.formatInvokeError("Invocation failure", args), targetException); } } }
最终调用 Method 的invoke 来反射执行相关方法。当然 GET 请求和POST 请求等的处理方式是不一样的,但最终原理都是一样的。