SpringMVC---拦截器源码学习

多个拦截器的执行流程:

       1、applyPreHandle方法。按照配置的顺序执行拦截其中的preHandle方法,并记下最后放行的拦截器的索引。如果都放行则不执行applyPreHandle方法中对应拦截器的afterCompletion函数的方法;只要有一个拦截器不放行,按照之前记录的索引倒序执行applyPreHandle方法中对应拦截器的afterCompletion函数的方法,下面的所有步骤都不执行。
       2、handle方法。执行目标方法。若目标方法没有发生异常,正常执行下面的方法;如果该方法发生异常,则在doDispatch方法里面会catch到并按照之前记录的索引倒序执行handle方法中对应拦截器的afterCompletion函数的方法,而且不会执行后面的方法(拦截器的postHandle方法和渲染页面方法)。
       3、applyPostHandle方法。倒序执行拦截器的postHandle方法。
       4、processDispatchResult方法。若目标方法没有发生异常,目标方法最后会按照之前记录的索引倒序执行processDispatchResult方法中拦截器的afterCompletion函数的方法;如果该方法发生异常,则在doDispatch方法里面会catch到并按照之前记录的索引倒序执行拦截器的afterCompletion方法。



接受源码的制裁吧

	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;
	                Object dispatchException = null;
	
	                try {
	                    processedRequest = this.checkMultipart(request);
	                    multipartRequestParsed = processedRequest != request;
	                    mappedHandler = this.getHandler(processedRequest);
	                    if (mappedHandler == null) {
	                        this.noHandlerFound(processedRequest, response);
	                        return;
	                    }
	
	                    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 ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
	                            return;
	                        }
	                    }
	                    
						//调用拦截器的preHandle方法
	                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
	                        return;
	                    }
	
	                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
	                    if (asyncManager.isConcurrentHandlingStarted()) {
	                        return;
	                    }
	
	                    this.applyDefaultViewName(processedRequest, mv);
	                    
	                    //调用拦截器的postHandle方法
	                    mappedHandler.applyPostHandle(processedRequest, response, mv);
	                } catch (Exception var20) {
	                    dispatchException = var20;
	                } catch (Throwable var21) {
	                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
	                }
	
	                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);	//页面渲染
	            } catch (Exception var22) {
	                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
	            } catch (Throwable var23) {
	                this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
	            }
	
	        } finally {
	            if (asyncManager.isConcurrentHandlingStarted()) {
	                if (mappedHandler != null) {
	                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
	                }
	            } else if (multipartRequestParsed) {
	                this.cleanupMultipart(processedRequest);
	            }
	
	        }
	    }
	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
	        HandlerInterceptor[] interceptors = this.getInterceptors();
	        if (!ObjectUtils.isEmpty(interceptors)) {
	            for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {	//拦截器的preHandle方法返回true的时候顺带记录索引
	                HandlerInterceptor interceptor = interceptors[i];
	                if (!interceptor.preHandle(request, response, this.handler)) {	//一旦有个前置处理器没放行, 执行拦截器的afterCompletion方法
	                    this.triggerAfterCompletion(request, response, (Exception)null);
	                    return false;
	                }
	            }
	        }
	
	        return true;
	    }
	void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
	        HandlerInterceptor[] interceptors = this.getInterceptors();
	        if (!ObjectUtils.isEmpty(interceptors)) {
	            for(int i = interceptors.length - 1; i >= 0; --i) {
	                HandlerInterceptor interceptor = interceptors[i];
	                interceptor.postHandle(request, response, this.handler, mv);
	            }
	        }
	
	    }
	private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
	        boolean errorView = false;
	        if (exception != null) {
	            if (exception instanceof ModelAndViewDefiningException) {
	                this.logger.debug("ModelAndViewDefiningException encountered", exception);
	                mv = ((ModelAndViewDefiningException)exception).getModelAndView();
	            } else {
	                Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
	                mv = this.processHandlerException(request, response, handler, exception);
	                errorView = mv != null;
	            }
	        }
	
	        if (mv != null && !mv.wasCleared()) {
	            this.render(mv, request, response);	//页面炸了就不会执行下面的方法, 但会在doDispatch方法catch出来执行拦截器的afterCompletion方法
	            if (errorView) {
	                WebUtils.clearErrorRequestAttributes(request);
	            }
	        } else if (this.logger.isTraceEnabled()) {
	            this.logger.trace("No view rendering, null ModelAndView returned.");
	        }
	
	        if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
	            if (mappedHandler != null) {
	                mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
	            }
	
	        }
	    }
	void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception {
	        HandlerInterceptor[] interceptors = this.getInterceptors();
	        if (!ObjectUtils.isEmpty(interceptors)) {
	            for(int i = this.interceptorIndex; i >= 0; --i) {	//根据索引倒叙遍历
	                HandlerInterceptor interceptor = interceptors[i];
	
	                try {
	                    interceptor.afterCompletion(request, response, this.handler, ex);
	                } catch (Throwable var8) {
	                    logger.error("HandlerInterceptor.afterCompletion threw exception", var8);
	                }
	            }
	        }
	
	    }
发布了33 篇原创文章 · 获赞 5 · 访问量 2281

猜你喜欢

转载自blog.csdn.net/cj1561435010/article/details/104080112