注: SpringFramework的版本是4.3.x。java
圖1 DispatcherServlet的doService方法時序圖git
通常狀況下,咱們不會本身指定HandlerAdapter,因此只須要分析默認的狀況。首先看DispatcherServlet的方法initHandlerAdapters(ApplicationContext context),該方法中加載文件DispatcherServlet.properties中指定的HandlerAdapter,以下圖2所示,默認的HandlerAdapter有HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、AnnotationMethodHandlerAdapter。github
圖2 DispatcherServlet.properties指定的HandlerAdapterweb
HttpRequestHandlerAdapter類在spring-webmvc模塊,類圖以下圖3所示,較爲簡單。spring
圖3 HttpRequestHandlerAdapter的類圖session
HttpRequestHandlerAdapter的源碼以下List-1所示,由support的實現可知這個處理的狀況是:controller類實現了接口HttpRequestHandler的狀況。mvc
List-1 HttpRequestHandlerAdapter的support和handle方法源碼ide
public class HttpRequestHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof HttpRequestHandler); } @Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; } ... }
SimpleControllerHandlerAdapter類在spring-webmvc模塊中,它實現的HandlerAdapter接口是org.springframework.web.servlet.HandlerAdapter。ui
SimpleControllerHandlerAdapter的部分源碼以下List-2所示,由其support方法可知,這個類處理的是咱們定義的controller類實現了org.springframework.web.servlet.mvc.Controller接口的狀況。this
List-2 SimpleControllerHandlerAdapter的support及其它方法源碼
@Override public boolean supports(Object handler) { return (handler instanceof Controller); } @Override public void handleAction(ActionRequest request, ActionResponse response, Object handler) throws Exception { ((Controller) handler).handleActionRequest(request, response); } @Override public ModelAndView handleRender(RenderRequest request, RenderResponse response, Object handler) throws Exception { return ((Controller) handler).handleRenderRequest(request, response); } ......
AnnotationMethodHandlerAdapter在spring-webmvc模塊中,如今已經被Deprecated。
圖4 AnnotationMethodHandlerAdapter的類繼承圖
AnnotationMethodHandlerAdapter的support方法及其它以下,一眼看上去比上面分析的倆個複雜多了。
List-3 AnnotationMethodHandlerAdapter的support方法及其它方法源碼
@Override public boolean supports(Object handler) { return getMethodResolver(handler).hasHandlerMethods(); } @Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Class<?> clazz = ClassUtils.getUserClass(handler); Boolean annotatedWithSessionAttributes = this.sessionAnnotatedClassesCache.get(clazz); if (annotatedWithSessionAttributes == null) { annotatedWithSessionAttributes = (AnnotationUtils.findAnnotation(clazz, SessionAttributes.class) != null); this.sessionAnnotatedClassesCache.put(clazz, annotatedWithSessionAttributes); } if (annotatedWithSessionAttributes) { checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true); } else { checkAndPrepare(request, response, true); } // Execute invokeHandlerMethod in synchronized block if required. if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { return invokeHandlerMethod(request, response, handler); } } } return invokeHandlerMethod(request, response, handler); } ......
來看下AnnotationMethodHandlerAdapter的support方法時序圖,原圖在Github上。
圖5 AnnotationMethodHandlerAdapter的support時序圖