springmvc源码学习(七)DispatcherServlet请求流程分析


前言


一、doService( )

将一些属性放入request中,如WebApplicationContext、localeResolver、themeResolver等,之后调用doDispatch( )方法进行请求的分发。

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

		// Keep a snapshot of the request attributes in case of an include,
		// to be able to restore the original attributes after the include.
		Map<String, Object> attributesSnapshot = null;
		if (WebUtils.isIncludeRequest(request)) {
    
    
			attributesSnapshot = new HashMap<>();
			Enumeration<?> attrNames = request.getAttributeNames();
			while (attrNames.hasMoreElements()) {
    
    
				String attrName = (String) attrNames.nextElement();
				if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
    
    
					attributesSnapshot.put(attrName, request.getAttribute(attrName));
				}
			}
		}

		// Make framework objects available to handlers and view objects.
		//设置WebApplicationContext
		request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
		//设置localeResolver
		request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
		//设置themeResolver
		request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
		//设置ThemeSource
		request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());

		if (this.flashMapManager != null) {
    
    
			FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
			if (inputFlashMap != null) {
    
    
			//设置FlashMap 
				request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
			}
			request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
			request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
		}

		RequestPath previousRequestPath = null;
		if (this.parseRequestPath) {
    
    
			previousRequestPath = (RequestPath) request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE);
			ServletRequestPathUtils.parseAndCache(request);
		}

		try {
    
    
			doDispatch(request, response);
		}
		finally {
    
    
			if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
    
    
				// Restore the original attribute snapshot, in case of an include.
				if (attributesSnapshot != null) {
    
    
					restoreAttributesAfterInclude(request, attributesSnapshot);
				}
			}
			if (this.parseRequestPath) {
    
    
				ServletRequestPathUtils.setParsedRequestPath(previousRequestPath, request);
			}
		}
	}

二、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 {
    
    
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
    
    
				//处理文件上传请求
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// Determine handler for the current request.
				//获取handler的执行器链
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null) {
    
    
					//没有找到handler
					noHandlerFound(processedRequest, response);
					return;
				}

				// Determine handler adapter for the current request.
				//获取处理器适配器
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				// Process last-modified header, if supported by the handler.
				String method = request.getMethod();
				boolean isGet = HttpMethod.GET.matches(method);
				if (isGet || HttpMethod.HEAD.matches(method)) {
    
    
					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
    
    
						//GET请求,并且上次访问到现在没有被修改过,直接返回
						return;
					}
				}
				
				//拦截器链的预处理applyPreHandle
				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    
    
					return;
				}

				// Actually invoke the handler.
				//处理业务
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				if (asyncManager.isConcurrentHandlingStarted()) {
    
    
					return;
				}
				
				
				applyDefaultViewName(processedRequest, mv);
				//拦截器链的后处理applyPostHandle
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			catch (Exception ex) {
    
    
				dispatchException = ex;
			}
			catch (Throwable err) {
    
    
				// As of 4.3, we're processing Errors thrown from handler methods as well,
				// making them available for @ExceptionHandler methods and other scenarios.
				dispatchException = new NestedServletException("Handler dispatch failed", err);
			}
			//执行结果的处理,如视图的渲染,请求的跳转、重定向等
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
    
    
			//拦截器链执行完毕回调
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		catch (Throwable err) {
    
    
			triggerAfterCompletion(processedRequest, response, mappedHandler,
					new NestedServletException("Handler processing failed", err));
		}
		finally {
    
    
			if (asyncManager.isConcurrentHandlingStarted()) {
    
    
				// Instead of postHandle and afterCompletion
				if (mappedHandler != null) {
    
    
					mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				}
			}
			else {
    
    
				// Clean up any resources used by a multipart request.
				//清理文件上传资源
				if (multipartRequestParsed) {
    
    
					cleanupMultipart(processedRequest);
				}
			}
		}
	}

Guess you like

Origin blog.csdn.net/RenshenLi/article/details/118882159