SpringMvc DispatherServlet

SpringMvc的使用都会在web.xml中配置 <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*:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup><!--大于0表示服务容器启动后,自动创建DispatcherServlet 容器--> </servlet>

<servlet-mapping>
	<servlet-name>springmvc</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>

@SuppressWarnings("serial") public class DispatcherServlet extends FrameworkServlet { 源码中它是 FrameworkServlet 的子类

@SuppressWarnings("serial") public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {

FrameworkServlet又是 HttpServletBean 的子类,HttpServletBean 又是HttpServlet的子类

public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware { HttpServletBean 是 HttpServlet的子类

所以DispatcherServlet本质上就是一个java servlet,里面有init,doGet,doPost,doService等一些列的方法

下面是对DispatcherServlet类的解析

private static final Properties defaultStrategies;

static {
	// Load default strategy implementations from properties file.
	// This is currently strictly internal and not meant to be customized
	// by application developers.
	try {
		ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
		defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
	}
	catch (IOException ex) {
		throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
	}
}

类中的静态代码块,类在被实例化的时候,执行此代码块,加载DispatcherServlet.class类同目录下的DispatcherServlet.properties properties文件,此文件是不可修改的

输入图片说明

[输入图片说明]

properties,文件里面是springmvc默认加载的,用户区域解析器,样式解析器,处理者的映射,处理者的适配器,处理者的异常解析器,视图解析器等

@Override
protected void onRefresh(ApplicationContext context) {
	initStrategies(context);
}

/**
 * Initialize the strategy objects that this servlet uses.
 * <p>May be overridden in subclasses in order to initialize further strategy objects.
 */
protected void initStrategies(ApplicationContext context) {
	initMultipartResolver(context); //文件解析器
	initLocaleResolver(context);//区域解析器,本地化解析
	initThemeResolver(context);//主题解析器
	initHandlerMappings(context);//handler映射(到Controller中的menthod)
	initHandlerAdapters(context);//handler适配器(执行映射对应的method)
	initHandlerExceptionResolvers(context);//处理者的异常解析器
	initRequestToViewNameTranslator(context);//请求到视图名称的转换,可以处理那些返回view为空的modelAndView ,它可以根据Request获取view的名称
	initViewResolvers(context);//视图解析器
	initFlashMapManager(context);//flash的映射管理
}

DispatcherServlet容器创建后,会执行onRefresh方法,去刷新所创建的容器,initStrategies方法则会加载 这九个默认的解析器

DisPathcherServlet的核心方法doService

@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;  //利用map缓存Request中的Attribute内容
	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.
	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));
	}
	request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
	request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

	try {
		doDispatch(request, response); //这个是doService中实际执行的方法
	}
	finally {
		if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
			// Restore the original attribute snapshot, in case of an include.
			if (attributesSnapshot != null) {
				restoreAttributesAfterInclude(request, attributesSnapshot); //将缓存到attributesSnapshot中的值,回填到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.
			mappedHandler = getHandler(processedRequest); //获取map处理器
			if (mappedHandler == null || mappedHandler.getHandler() == null) {
                            //没有找到对应url的maping
				noHandlerFound(processedRequest, response);
				return;
			}

			// Determine handler adapter for the current request.
			HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());//根据map获取相应的适配器

			// Process last-modified header, if supported by the handler.
			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;
				}
			}

			if (!mappedHandler.applyPreHandle(processedRequest, response)) {//执行interceptor.preHandle,在处理函数之前执行的方法
				return;
			}

			// Actually invoke the handler.,执行处理函数,即项目中的Controller中对应url的方法
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //获取适配器里面对应的方法,返回视图


			if (asyncManager.isConcurrentHandlingStarted()) {
				return;
			}

			applyDefaultViewName(request, mv);
                            //这里执行interceptor.postHandle,在处理函数之前执行的方法
			mappedHandler.applyPostHandle(processedRequest, response, mv);
		}
		catch (Exception ex) {
			dispatchException = ex;
		}

		processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);//进行自定义异常解,视图的解析
	}
	catch (Exception ex) {
                    //捕获异常,这里执行interceptor的afterCompletion方法 
		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);
			}
		}
	}
}

转载于:https://my.oschina.net/u/3195939/blog/841676

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值