【SpringMvc执行流程】SpringMvc中的HandlerAdapter handle方法使用(六)

doService方法开始查看

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {

    request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
    request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
    request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
    request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
    doDispatch(request, response);
}

前面都是必要参数绑定,doDispatch是我们要看的重点。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    Exception dispatchException = null;
    HandlerExecutionChain mappedHandler = null;
    ModelAndView mv = null;
    HttpServletRequest processedRequest = request;
    mappedHandler = getHandler(processedRequest);
    MyHandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}

结合上述文章,这里就很容易看懂了。

  • getHandler是根据请求,从mappingRegisty获取到和请求相关的HandlerExecutionChain。而HandlerExecutionChain中有个Object对象handler,其实这个对象就是HandlerMethod。再根据HandlerMethod获取能够处理此对象的HandlerAdapter,进行handle方法调用。
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {

    return handleInternal(request, response, (HandlerMethod) handler);
}

handle方法是使用了适配器模式,放在了AbstractHandlerMethodAdapter抽象类中,不同的具体实现类有不同的实现方式。

protected ModelAndView handleInternal(HttpServletRequest request,
                                        HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

    MyModelAndView mav;

    mav = invokeHandlerMethod(request, response, handlerMethod);

    return mav;
}

invokeHandlerMethod又名称可知,应该是对方法的调用。

protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
                                           HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

    ServletWebRequest webRequest = new ServletWebRequest(request, response);
    try {
        //@InitBinder处理
        WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
        //@ModelAttribute处理
        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);


        //执行Controller中的RequestMapping注释的方法
        invocableMethod.invokeAndHandle(webRequest, mavContainer);

        return getModelAndView(mavContainer, modelFactory, webRequest);
    }
    finally {
        webRequest.requestCompleted();
    }
}
  • getDataBinderFactory是对注解@InitBinder处理。

  • getModelFactory是对注解@ModelAttribute处理。

  • setHandlerMethodArgumentResolvers中添加的argumentResolvers正式我们在RequestMappingHandlerMapping中初始化时回调aftePropertiesSet赋值的处理方式。

  • returnValueHandlers也是如此,是对返回值的处理方式。

关键的执行方法是ServletInvocableHandlerMethod的invokeAndHandle方法。

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
                            Object... providedArgs) throws Exception {

    Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
    setResponseStatus(webRequest);

    if (returnValue == null) {
        if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
            mavContainer.setRequestHandled(true);
            return;
        }
    }
    else if (StringUtils.hasText(getResponseStatusReason())) {
        mavContainer.setRequestHandled(true);
        return;
    }

    mavContainer.setRequestHandled(false);
    Assert.state(this.returnValueHandlers != null, "No return value handlers");

    this.returnValueHandlers.handleReturnValue(
            returnValue, getReturnValueType(returnValue), mavContainer, webRequest);

}

通过invokeForRequest方法执行具体方法,并获取执行后的返回值,这里看下示例来说明:

@GetMapping(value = "hello")
public String index(String name) {
    System.out.println(name);
    return "index";
}

这里returnValue就是返回的index。

returnValueHandlers就是对返回值做处理,处理的结果放入mavContaioner中,供后续的getModelAndView方法使用。(请求时,是如何处理参数,是如何对返回值进行处理,后续做详细介绍)。

private MyModelAndView getModelAndView(ModelAndViewContainer mavContainer,ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
    modelFactory.updateModel(webRequest, mavContainer);
    ModelMap model = mavContainer.getModel();
    MyModelAndView mav = new MyModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
    return mav;
}

这里其实就是创建了一个ModelAndView


文章作者: Ciwei
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Ciwei !
  目录