• SpringMVC源码阅读RequestMappingHandlerAdapter如何处理Handle(八)


    接口

    public interface HandlerAdapter {
            /**
             * 是否能处理指定Handler
             * @param var1
             * @return
             */
            boolean supports(Object var1);
    
            /**
             * 处理Handler
             * @param var1
             * @param var2
             * @param var3
             * @return
             * @throws Exception
             */
            @Nullable
            ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
    
            /**
             * 获取资源最后一次更新时间
             * @param var1
             * @param var2
             * @return
             */
            long getLastModified(HttpServletRequest var1, Object var2);
        }

    类图

     我们回到Dispatcher开始看起

    DispatcherServlet

    doDispatch

    org.springframework.web.servlet.FrameworkServlet#service

    ->

    org.springframework.web.servlet.FrameworkServlet#processRequest

    ->

    org.springframework.web.servlet.DispatcherServlet#doService

    ->

    org.springframework.web.servlet.DispatcherServlet#doDispatch

        protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
            HttpServletRequest processedRequest = request;
            HandlerExecutionChain mappedHandler = null;
            boolean multipartRequestParsed = false;
            //获取异步管理器
            WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
            try {
                try {
                    ModelAndView mv = null;
                    Exception dispatchException = null;
    
                    try {
                        /**
                         * 如果配置了MultipartResolver 会调用 isMultipart() 方法判断请求中是否包含文件。
                         * 如果请求数据中包含文件,则调用 MultipartResolver 的 resolveMultipart()
                         * 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile
                         * 并封装在 MultipartHttpServletRequest (继承了 HttpServletRequest) 对象中并返回
                         */
                        processedRequest = this.checkMultipart(request);
                        //是否被解析
                        multipartRequestParsed = processedRequest != request;
                        //通过HandlerMapping获得 HandlerExecutionChanin如:org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
                        //org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMappin
                        mappedHandler = this.getHandler(processedRequest);
                        if (mappedHandler == null || mappedHandler.getHandler() == null) {
                            //没获取到抛出404异常
                            this.noHandlerFound(processedRequest, response);
                            return;
                        }
                        //<1>返回对应能处理的HandlerAdapter
                        HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                        String method = request.getMethod();
                        boolean isGet = "GET".equals(method);
                        if (isGet || "HEAD".equals(method)) {
                            long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                            if (this.logger.isDebugEnabled()) {
                                this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                            }
    
                            if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                                return;
                            }
                        }
                        //<前置处理 拦截器
                        if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                            return;
                        }
                        //<3>真正的处理方法 返回视图 没有视图则返回null
                        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                        //是否开启异步管理器
                        if (asyncManager.isConcurrentHandlingStarted()) {
                            return;
                        }
                        //设置默认的viewName
                        this.applyDefaultViewName(processedRequest, mv);
                        //后置处理 拦截器
                        mappedHandler.applyPostHandle(processedRequest, response, mv);
                    } catch (Exception var19) {
                        dispatchException = var19;
                    }
                    //处理正常和异常的请求调用结果。
                    this.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
                } catch (Exception var20) {
                    //触发异常拦截器的AfterCompletion实现
                    this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20);
                } catch (Error var21) {
                    //触发异常拦截器的AfterCompletion实现
                    this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21);
                }
    
            } finally {
                if (asyncManager.isConcurrentHandlingStarted()) {
                    if (mappedHandler != null) {
                        mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                    }
                } else if (multipartRequestParsed) {
                    this.cleanupMultipart(processedRequest);
                }
    
            }
        }

    <1>getHandlerAdapter

    org.springframework.web.servlet.FrameworkServlet#service

    ->

    org.springframework.web.servlet.FrameworkServlet#processRequest

    ->

    org.springframework.web.servlet.DispatcherServlet#doService

    ->

    org.springframework.web.servlet.DispatcherServlet#doDispatch

    ->

    org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter

     protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
            if (this.handlerAdapters != null) {
                Iterator var2 = this.handlerAdapters.iterator();
    
                while(var2.hasNext()) {
                    HandlerAdapter adapter = (HandlerAdapter)var2.next();
                    //<2>遍历所有适配器 传入handler 判断判断adapter是否能处理
                    if (adapter.supports(handler)) {
                        return adapter;
                    }
                }
            }
    
            throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
        }

    RequestMappingHandlerAdapter

    <2>supports

    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supports

    public final boolean supports(Object handler) {
            //判断Handler是否是HandlerMethod 类型 supportsInternal是个抽象方法由子类实现 也就是RequestMappingHandlerAdapter
            return handler instanceof HandlerMethod && this.supportsInternal((HandlerMethod)handler);
        }

    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supports

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#supportsInternal

    protected boolean supportsInternal(HandlerMethod handlerMethod) {
            return true;
        }

    <3>handle

    org.springframework.web.servlet.FrameworkServlet#service

    ->

    org.springframework.web.servlet.FrameworkServlet#processRequest

    ->

    org.springframework.web.servlet.DispatcherServlet#doService

    ->

    org.springframework.web.servlet.DispatcherServlet#doDispatch

    ->

    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle

     public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //<4>调用子类的实现 抽象方法模板方法实现
            return this.handleInternal(request, response, (HandlerMethod)handler);
        }

    <4>handleInternal

    org.springframework.web.servlet.FrameworkServlet#service

    ->

    org.springframework.web.servlet.FrameworkServlet#processRequest

    ->

    org.springframework.web.servlet.DispatcherServlet#doService

    ->

    org.springframework.web.servlet.DispatcherServlet#doDispatch

    ->

    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

    protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
            //<5>检查是否配置了只能处理请求 以及是否必须存在session而没有传
            this.checkRequest(request);
            ModelAndView mav;
            //是否有配置根据session加锁
            if (this.synchronizeOnSession) {
                //true为如果不存在session则创建一个并返回  false不存在直接返回null
                HttpSession session = request.getSession(false);
                if (session != null) {
                    /**
                     *  Object mutex = session.getAttribute(SESSION_MUTEX_ATTRIBUTE);
                     *  如果为空则返回当前session对象 当我们有需求保证一个session原子性的时候用吧 就一个加同步锁动作
                     */
                    Object mutex = WebUtils.getSessionMutex(session);
                    synchronized(mutex) {
                        //<6>执行处理返回modelView
                        mav = this.invokeHandlerMethod(request, response, handlerMethod);
                    }
                } else {
                    //<6>执行处理返回modelView
                    mav = this.invokeHandlerMethod(request, response, handlerMethod);
                }
            } else {
                //<6>执行处理求返回modelView
                mav = this.invokeHandlerMethod(request, response, handlerMethod);
            }
    
            /**
             * 响应头Cache-Control是通知浏览器缓存
             * 这里主要是@SessionAttribute用法的处理
             * 很少用到 也可兼容https://blog.csdn.net/qq_38737992/article/details/89763067 处理
             */
            if (!response.containsHeader("Cache-Control")) {
                if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
                    this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
                } else {
                    this.prepareResponse(response);
                }
            }
    
            return mav;
        }

    <5>checkRequest

    org.springframework.web.servlet.FrameworkServlet#service

    ->

    org.springframework.web.servlet.FrameworkServlet#processRequest

    ->

    org.springframework.web.servlet.DispatcherServlet#doService

    ->

    org.springframework.web.servlet.DispatcherServlet#doDispatch

    ->

    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

    ->

    org.springframework.web.servlet.support.WebContentGenerator#checkRequest

    protected final void checkRequest(HttpServletRequest request) throws ServletException {
            //获得请求方式
            String method = request.getMethod();
            //判断是否支持  我们可以通过这个支持的请求方式
            if (this.supportedMethods != null && !this.supportedMethods.contains(method)) {
                throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods);
                //判断是否配置了必须存在session 
            } else if (this.requireSession && request.getSession(false) == null) {
                throw new HttpSessionRequiredException("Pre-existing session required but none found");
            }
        }

    <6>invokeHandlerMethod

    org.springframework.web.servlet.FrameworkServlet#service

    ->

    org.springframework.web.servlet.FrameworkServlet#processRequest

    ->

    org.springframework.web.servlet.DispatcherServlet#doService

    ->

    org.springframework.web.servlet.DispatcherServlet#doDispatch

    ->

    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod

     protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
            ServletWebRequest webRequest = new ServletWebRequest(request, response);
    
            ModelAndView var15;
            try {
                WebDataBinderFactory binderFactory = this.getDataBinderFactory(handlerMethod);
                ModelFactory modelFactory = this.getModelFactory(handlerMethod, binderFactory);
                //交给ServletInvocableHandlerMethod 对象代理handlerMethod
                ServletInvocableHandlerMethod invocableMethod = this.createInvocableHandlerMethod(handlerMethod);
                //入参绑定器 set 后续使用
                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);
                //DeferredResult方式拦截器
                asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
                Object result;
                /**
                 * 主要针对我们返回值是Callable 会释放Dispatcher占用的线程 交给的taskExecutor之心你那个 但是与客户端连接还保持
                 * 当拿回结果 从新走Dispatcher入口进来 这里判断就会是true
                 */
                if (asyncManager.hasConcurrentResult()) {
                    result = asyncManager.getConcurrentResult();
                    mavContainer = (ModelAndViewContainer)asyncManager.getConcurrentResultContext()[0];
                    asyncManager.clearConcurrentResult();
                    LogFormatUtils.traceDebug(this.logger, (traceOn) -> {
                        String formatted = LogFormatUtils.formatValue(result, !traceOn);
                        return "Resume with async result [" + formatted + "]";
                    });
                    //同时这类替换invocableMethod为ServletInvocableHandlerMethod.ConcurrentResultHandlerMethod 继承ServletInvocableHandlerMethod
                    invocableMethod = invocableMethod.wrapConcurrentResult(result);
                }
                //<7>执行后续请求处理
                invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);
                if (asyncManager.isConcurrentHandlingStarted()) {
                    result = null;
                    return (ModelAndView)result;
                }
                //<如果我们返回ModelAndView则会被ModelAndViewMethodReturnValueHandler 封装到 mavContainenr 这里则根据MavContainer获取
                var15 = this.getModelAndView(mavContainer, modelFactory, webRequest);
            } finally {
                webRequest.requestCompleted();
            }
    
            return var15;
        }

    ServletInvocableHandlerMethod

    <7>invokeAndHandle

    org.springframework.web.servlet.FrameworkServlet#service

    ->

    org.springframework.web.servlet.FrameworkServlet#processRequest

    ->

    org.springframework.web.servlet.DispatcherServlet#doService

    ->

    org.springframework.web.servlet.DispatcherServlet#doDispatch

    ->

    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod

    ->

    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

      public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
            //<7_1>执行参数绑定  执行控制器方法取回返回结果
            Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs);
            this.setResponseStatus(webRequest);
            if (returnValue == null) {
                if (this.isRequestNotModified(webRequest) || this.getResponseStatus() != null || mavContainer.isRequestHandled()) {
                    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 {
                //<10>通过返回值处理器进行返回值处理
                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;
            }
        }

    <7_1>invokeForRequest

    org.springframework.web.servlet.FrameworkServlet#service

    ->

    org.springframework.web.servlet.FrameworkServlet#processRequest

    ->

    org.springframework.web.servlet.DispatcherServlet#doService

    ->

    org.springframework.web.servlet.DispatcherServlet#doDispatch

    ->

    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod

    ->

    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

    ->

    org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest

     public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
            //<8>通过绑定器绑定参数
            Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Arguments: " + Arrays.toString(args));
            }
            //<9>调用对应的controller方法
            return this.doInvoke(args);
        }

    <8>getMethodArgumentValues

    org.springframework.web.method.support.InvocableHandlerMethod#getMethodArgumentValues

     protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
            //获得对应的绑定参数
            MethodParameter[] parameters = this.getMethodParameters();
            Object[] args = new Object[parameters.length];
    
            for(int i = 0; i < parameters.length; ++i) {
                MethodParameter parameter = parameters[i];
                parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
                //这里是优先获取 @Init方法注册的合适的绑定器 返回的类型绑定器
                args[i] = this.resolveProvidedArgument(parameter, providedArgs);
                if (args[i] == null) {
                    //遍历所有参数绑定器找到合适的绑定器
                    if (this.argumentResolvers.supportsParameter(parameter)) {
                        try {
                            //解析出参数 
                            args[i] = this.argumentResolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
                        } catch (Exception var10) {
                            if (this.logger.isDebugEnabled()) {
                                String message = var10.getMessage();
                                if (message != null && !message.contains(parameter.getExecutable().toGenericString())) {
                                    this.logger.debug(formatArgumentError(parameter, message));
                                }
                            }
    
                            throw var10;
                        }
                    } else if (args[i] == null) {
                        throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
                    }
                }
            }
            //返回参数 
            return args;
        }

    <9>doInvoke

    org.springframework.web.method.support.InvocableHandlerMethod#doInvoke

      protected Object doInvoke(Object... args) throws Exception {
            ReflectionUtils.makeAccessible(this.getBridgedMethod());
    
            try {
                //反射调用对应的Method方法
                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);
                }
            }
        }

     <10>handleReturnValue

    org.springframework.web.method.support.InvocableHandlerMethod#handleReturnValue

      public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
             //<11>根据响应值和响应参数选取合适的BindType
            HandlerMethodReturnValueHandler handler = this.selectHandler(returnValue, returnType);
            if (handler == null) {
                throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
            } else {
                //写入body 我们可以自定义绑定在写入之前执行一些逻辑
                handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
            }
        }

    <11>selectHandler

    org.springframework.web.method.support.InvocableHandlerMethod#selectHandler

      @Nullable
        private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) {
            boolean isAsyncValue = this.isAsyncReturnValue(value, returnType);
            Iterator var4 = this.returnValueHandlers.iterator();
    
            HandlerMethodReturnValueHandler handler;
            do {
                do {
                    if (!var4.hasNext()) {
                        return null;
                    }
    
                    handler = (HandlerMethodReturnValueHandler)var4.next();
                } while(isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler));
                //返回supportsReturnType  调用判断是否能处理
            } while(!handler.supportsReturnType(returnType));
    
            return handler;
        }

    如:RequestBody绑定器的实现

     public boolean supportsReturnType(MethodParameter returnType) {
            return AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class);
        }

    总结

    1.RequestMappingHandlerAdapter最终内部会将请求委托给ServletInvocableHandlerMethod处理

    2.ServletInvocableHandlerMethod 会先经过参数绑定器获得参数args数组

    3.然后通能反射调用Controller的对应方法

    4.再通过响应绑定器对不同的响应内容做处理 比如解析@ResponseBody的响应处理器

  • 相关阅读:
    C# 运用StreamReader类和StreamWriter类实现文件的读写操作
    C# 理解FileInfo类的Open()方法
    C# 运用FileInfo类创建、删除文件
    C# 创建子目录
    C# 目录下的文件操作
    C# 运用DirectoryInfo类和FileInfo类
    C# 文件操作概述
    LINUX介绍
    linux iso 下载地址
    ADO.NET梳理
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12222381.html
Copyright © 2020-2023  润新知