springMVC源码分析--DispatcherServlet请求获取及处理

转载:https://blog.csdn.net/qq924862077/article/details/53523713

DispatcherServlet其实就是一个HttpServlet,其实他是HttpServlet的子类,所以它和普通的HttpServlet有同样的配置:

	<servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
	    <init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc-config.xml</param-value>
		</init-param>
        <load-on-startup>1</load-on-startup>    
	</servlet>
 
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

 

@Override
	protected final void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
 
		processRequest(request, response);
	}

 

@Override
	protected final void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
 
		processRequest(request, response);
	}

processRequest的实现是在FrameworkServlet中,此方法中最主要的操作就是调用doService方法

protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
 
		long startTime = System.currentTimeMillis();
		Throwable failureCause = null;
 
		LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
		LocaleContext localeContext = buildLocaleContext(request);
 
		RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
 
		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
		asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());
 
		initContextHolders(request, localeContext, requestAttributes);
 
		try {
			doService(request, response);
		}
		catch (ServletException ex) {
			failureCause = ex;
			throw ex;
		}
		catch (IOException ex) {
			failureCause = ex;
			throw ex;
		}
		catch (Throwable ex) {
			failureCause = ex;
			throw new NestedServletException("Request processing failed", ex);
		}
 
		finally {
			resetContextHolders(request, previousLocaleContext, previousAttributes);
			if (requestAttributes != null) {
				requestAttributes.requestCompleted();
			}
 
			if (logger.isDebugEnabled()) {
				if (failureCause != null) {
					this.logger.debug("Could not complete request", failureCause);
				}
				else {
					if (asyncManager.isConcurrentHandlingStarted()) {
						logger.debug("Leaving response open for concurrent processing");
					}
					else {
						this.logger.debug("Successfully completed request");
					}
				}
			}
 
			publishRequestHandledEvent(request, response, startTime, failureCause);
		}
	}

 doService方法的最终实现是在DispatcherServlet中,这样所有的Http请求(GET、POST、PUT和DELETE等)的最终操作就DispatcherServlet中实现了。
DispatcherServlet中doService的实现如下,对Request设置了一些全局属性,最终接下来的操作是在doDispatcher函数中实现了。

//获取请求,设置一些request的参数,然后分发给doDispatch
	@Override
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
		if (logger.isDebugEnabled()) {
			String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
			logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
					" processing " + request.getMethod() + " request for [" + getRequestUri(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<String, Object>();
			Enumeration<?> attrNames = request.getAttributeNames();
			while (attrNames.hasMoreElements()) {
				String attrName = (String) attrNames.nextElement();
				if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
					attributesSnapshot.put(attrName, request.getAttribute(attrName));
				}
			}
		}
 
		// Make framework objects available to handlers and view objects.
		/* 设置web应用上下文**/
		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());
		//请求刷新时保存属性
		FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
		if (inputFlashMap != null) {
			request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
		}
		//Flash attributes 在对请求的重定向生效之前被临时存储(通常是在session)中,并且在重定向之后被立即移除
		request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
		//FlashMap 被用来管理 flash attributes 而 FlashMapManager 则被用来存储,获取和管理 FlashMap 实体.
		request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
 
		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);
				}
			}
		}
	}

doDispatch函数中完成了对一个请求的所有操作 

/**
	 *将Handler进行分发,handler会被handlerMapping有序的获得
	 *通过查询servlet安装的HandlerAdapters来获得HandlerAdapters来查找第一个支持handler的类
	 *所有的HTTP的方法都会被这个方法掌控。取决于HandlerAdapters 或者handlers 他们自己去决定哪些方法是可用
	 *@param request current HTTP request
	 *@param response current HTTP response
	 */
	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		/* 当前HTTP请求**/
		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);
 
				// 获得HandlerExecutionChain,其包含HandlerIntercrptor和HandlerMethod
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null || mappedHandler.getHandler() == null) {
					noHandlerFound(processedRequest, response);
					return;
				}
 
				
				//获得HandlerAdapter
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
 
				//获得HTTP请求方法
				String method = request.getMethod();
				boolean isGet = "GET".equals(method);
				if (isGet || "HEAD".equals(method)) {
					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
					if (logger.isDebugEnabled()) {
						logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
					}
					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
						return;
					}
				}
				//如果有拦截器的话,会执行拦截器的preHandler方法
				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}
 
				//返回ModelAndView
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
 
				if (asyncManager.isConcurrentHandlingStarted()) {
					return;
				}
				//当view为空时,,根据request设置默认view
				applyDefaultViewName(processedRequest, mv);
				//执行拦截器的postHandle
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			catch (Exception ex) {
				dispatchException = ex;
			}
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		catch (Error err) {
			triggerAfterCompletionWithError(processedRequest, response, mappedHandler, 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);
				}
			}
		}
	}

调用完doDispatch之后就完成了一个请求的访问,其会将渲染后的页面或者数据返回给请求发起者。

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringMVC 是 Spring 框架的一部分,主要用于构建 Web 应用程序。它采用了基于请求的模型,通过将请求映射到控制器类和处理方法来处理请求,并使用视图解析器来渲染响应。SpringMVC 的核心是 DispatcherServlet,它充当前端控制器,负责协调处理请求,并调用适当的处理器来处理请求。 下面是 SpringMVC源码分析: 1. DispatcherServletDispatcherServletSpringMVC 的核心类,它充当前端控制器,负责协调处理请求,并调用适当的处理器来处理请求DispatcherServlet 的主要任务是将请求委托给适当的处理器来处理,然后将处理结果返回给客户端。 2. HandlerMapping:HandlerMapping 是一个接口,用于将请求映射到控制器类和处理方法。SpringMVC 提供了多种 HandlerMapping 实现,例如 BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping 和 RequestMappingHandlerMapping 等。 3. HandlerAdapter:HandlerAdapter 是一个接口,用于将请求委托给适当的处理器来处理SpringMVC 提供了多种 HandlerAdapter 实现,例如 SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter 和 HttpRequestHandlerAdapter 等。 4. HandlerInterceptor:HandlerInterceptor 是一个接口,用于在控制器执行之前或之后执行一些操作。SpringMVC 提供了多种 HandlerInterceptor 实现,例如 LocaleChangeInterceptor、ThemeChangeInterceptor 和 HandlerInterceptorAdapter 等。 5. ViewResolver:ViewResolver 是一个接口,用于将逻辑视图名称解析为实际的视图对象。SpringMVC 提供了多种 ViewResolver 实现,例如 InternalResourceViewResolver、FreeMarkerViewResolver 和 VelocityViewResolver 等。 6. HandlerExceptionResolver:HandlerExceptionResolver 是一个接口,用于处理控制器抛出的异常。SpringMVC 提供了多种 HandlerExceptionResolver 实现,例如 SimpleMappingExceptionResolver、AnnotationMethodHandlerExceptionResolver 和 DefaultHandlerExceptionResolver 等。 7. ModelAndView:ModelAndView 是一个类,用于封装控制器处理结果和逻辑视图名称。它包含一个模型对象和一个视图名称。 总之,SpringMVC源码分析需要深入了解 Spring Framework 的各个方面,包括 IoC 容器、AOP、Servlet API 等。同时,需要对 Web 应用程序的基本概念和架构有一定的了解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值