SpringMVC源码分析-doDispatch

doDispatch方法执行流程图

网上随便找的张图片,地址:SpringMVC工作流程详解(11大执行流程步骤) – mikechen

在用户发送请求后,服务器执行经过DispatcherServlet,其中主要工作都在DispatcherServlet的doDispatch中,本文讲解doDispatch中的几个重要的方法

doDispatch中执行的主要的方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
         ....
        //1.获取HandlerExcutionChain (内部拥有Handler)
        HandlerExecutionChain mappedHandler = getHandler(processedRequest);
        ....        
        //2.获取控制器适配器
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        ....
        //3.执行handler方法 (如控制器),返回ModelAndView
        ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());    
        ....
        //4.执行拦截器postHandler
        mappedHandler.applyPostHandle(processedRequest, response, mv);
        .....
        //5.处理结果
        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

}

获取HandlerExecutionChain

//1.获取HandlerExcutionChain (内部拥有Handler)
HandlerExecutionChain mappedHandler = getHandler(processedRequest);

HandlerExecutionChain可以看作是一个Handler,内部有一个handler内部变量,这个handler就是具体的处理器。至于为什么是Object类型?是因为DispatchServlet处理多种请求,处理器Handler的种类多类型复杂,使用Object类型可以起到兼容的作用。(后面的HandlerAdpater是用来适配不同的Handler,这里用到了适配器模式,多种HandlerAdpater来适配不同的Handler来达到不同的作用。

getHandler()方法中,通过循环所有的HandlerMappings,执行getHandler方法来与`Handler匹配,匹配成功后,返回Handler

普通的请求方式,handlerMapping对应的是RequesMappingHandlerMapping,这里可以看到匹配handlerMapping之后,此时HandlerExecutionChain中的handler的类型是 HandlerMethod。所以,不同的请求类型有对赢得HandlerMapping映射,从而返回不同的类型的handler封装成HandlerExecutionChain

至于获取handler的方法 mapping.getHandler(request),是HandlerMapping接口的方法,具体实现在于不同的实现类当中,这里就不一一赘述

获取HandlerAdapter

通过HanlderExecutionChain中的handler,调用getHandlerAdapter方法获取HandlerAdapter

//2.获取控制器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

getHandlerAdapter中,通过遍历handlerAdapters,调用HandlerAdpater的support是方法,获取与handler相匹配的HandlerAdapter

普通请求的handlerAdapter对应的是RequestMappingHandlerAdapter

support方法是继承的AbstractHandlerMethodAdapter实现的,可以看到如果handler类型是HandlerMethod,并且supportsInternal(handler)方法返回true就匹配适配器。

supportsInternal方法又是一个接口,实现的地方在RequestMappingHandlerAdapter中,这里可以看到直接返回的就是true

其他类型的handler这里就不举例子了

执行控制器返回ModelAndView

控制中就是controller实际业务逻辑的地方,可以看到通过调用HandlerAdapter中的handler方法

// Actually invoke the handler.
ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

看看HandlerAdapter的实现类,以RequestMappingHandlerAdapter为例子,继承了AbstractHandlerMethodAdapter再继承HandlerAdapter接口

AbstractHandlerMethodAdapter中实现了handle方法

handleInternal方法又是一个接口,由RequestMappingHandlerAdapter实现

真正的逻辑也是这里面实现的

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

        ModelAndView mav;
        checkRequest(request);
        // 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) {
                    mav = invokeHandlerMethod(request, response, handlerMethod);
                }
            }
            else {
                // No HttpSession available -> no mutex necessary
                mav = invokeHandlerMethod(request, response, handlerMethod);
            }
        }
        else {
            // No synchronization on session demanded at all...
            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, 说明具体的逻辑也就在里面

结果处理

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

processDispatchResult方法是doDispatch中最后执行的一个方法,里面由处理异常、视图渲染、结果回调等功能的实现

    /**
     * Handle the result of handler selection and handler invocation, which is
     * either a ModelAndView or an Exception to be resolved to a ModelAndView.
     */a
    private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
            @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
            @Nullable Exception exception) throws Exception {

        boolean errorView = false;
         //1.异常处理
        if (exception != null) {
            if (exception instanceof ModelAndViewDefiningException) {
                logger.debug("ModelAndViewDefiningException encountered", exception);
                mv = ((ModelAndViewDefiningException) exception).getModelAndView();
            }
            else {
                Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
                mv = processHandlerException(request, response, handler, exception);
                errorView = (mv != null);
            }
        }
         //2.视图渲染
        // Did the handler return a view to render?
        if (mv != null && !mv.wasCleared()) {
            render(mv, request, response);
            if (errorView) {
                WebUtils.clearErrorRequestAttributes(request);
            }
        }
        else {
            if (logger.isTraceEnabled()) {
                logger.trace("No view rendering, null ModelAndView returned.");
            }
        }
        
        if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
            // Concurrent handling started during a forward
            return;
        }
        //3.回调
        if (mappedHandler != null) {
            // Exception (if any) is already handled..
            mappedHandler.triggerAfterCompletion(request, response, null);
        }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值