美文网首页
SpringMVC源码解析——Handler适配器

SpringMVC源码解析——Handler适配器

作者: 橙味菌 | 来源:发表于2019-08-09 11:02 被阅读0次

点击回顾SpringMVC请求响应流程

Handler适配器在DispatcherServlet的doDispatch方法中

  • 被创建(getHandlerAdapter方法)
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  ```

  查看getHandlerAdapter方法(看看它怎么创建HandlerAdapter的)

*   负责执行Handler执行链
    ```java
    // 适配器执行Handler执行链,返回ModelAndView
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());</pre>

查看HandlerAdapter接口

public interface HandlerAdapter {
​
 //是否支持handler的调用
 boolean supports(Object handler);
​

 //调用handler处理请求
 ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
​
 /**没弄明白
 * Same contract as for HttpServlet's {@code getLastModified} method.
 * Can simply return -1 if there's no support in the handler class.
 * @param request current HTTP request
 * @param handler handler to use
 * @return the lastModified value for the given handler
 * @see javax.servlet.http.HttpServlet#getLastModified
 * @see org.springframework.web.servlet.mvc.LastModified#getLastModified
 */
 long getLastModified(HttpServletRequest request, Object handler);
​
}
HandlerAdapter继承关系

查看抽象实现类AbstractHandlerMethodAdapter的handler方法(子类的实现)

发现它简单地调用handleInternal这一抽象方法,把具体的实现甩给了子类(漂亮的职责推卸)

查看子类RequestMappingHandlerAdapter的handlerInternal方法(对请求处理的实现)

protected ModelAndView handleInternal(HttpServletRequest request,
 HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
​
   ModelAndView mav;
   checkRequest(request);
​
   // 并发情况下在synchronized块调用invokeHandlerMethod
   if (this.synchronizeOnSession) {
     HttpSession session = request.getSession(false);
     if (session != null) {
       Object mutex = WebUtils.getSessionMutex(session);
       synchronized (mutex) {
         mav = invokeHandlerMethod(request, response, handlerMethod);
       }
     } else {
       // 不存在有效会话——不必考虑并发影响,直接调用
       mav = invokeHandlerMethod(request, response, handlerMethod);
     }
   }else {
     //无并发直接调用invokeHandlerMethod
     mav = invokeHandlerMethod(request, response, handlerMethod);
   }
​
   if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
     if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
       applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
     }else {
       prepareResponse(response);
     }
   }
​
   return mav;
}

可以看到这个方法最终是通过调用invokeHandlerMethod方法来获取ModelAndView并返回的

protected ModelAndView invokeHandlerMethod(...) throws Exception {
​
   ServletWebRequest webRequest = new ServletWebRequest(request, response);
   try {
     WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
     ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
​
     ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
     if (this.argumentResolvers != null) {
       invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
     }
     if (this.returnValueHandlers != null) {
       invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
     }
     invocableMethod.setDataBinderFactory(binderFactory);
     invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
​
     ModelAndViewContainer mavContainer = new ModelAndViewContainer();
     mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
     modelFactory.initModel(webRequest, mavContainer, invocableMethod);
     mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
​
     AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
     asyncWebRequest.setTimeout(this.asyncRequestTimeout);
​
     WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
     asyncManager.setTaskExecutor(this.taskExecutor);
     asyncManager.setAsyncWebRequest(asyncWebRequest);
     asyncManager.registerCallableInterceptors(this.callableInterceptors);
     asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
​
     if (asyncManager.hasConcurrentResult()) {
       Object result = asyncManager.getConcurrentResult();
       mavContainer = (ModelAndViewContainer)asyncManager.getConcurrentResultContext()[0];
       asyncManager.clearConcurrentResult();
       LogFormatUtils.traceDebug(logger, traceOn -> {
         String formatted = LogFormatUtils.formatValue(result, !traceOn);
         return "Resume with async result [" + formatted + "]";
         });
       invocableMethod = invocableMethod.wrapConcurrentResult(result);
     }
​
     invocableMethod.invokeAndHandle(webRequest, mavContainer);
     if (asyncManager.isConcurrentHandlingStarted()) {
       return null;
     }
​
     return getModelAndView(mavContainer, modelFactory, webRequest);
   }finally {
     webRequest.requestCompleted();
   }
}

相关文章

网友评论

      本文标题:SpringMVC源码解析——Handler适配器

      本文链接:https://www.haomeiwen.com/subject/deecjctx.html