古道长亭

Contact me with ixiaoqiang0011@gmail.com


  • 首页

  • 归档

  • 分类

  • 关于

  • Book

  • 搜索

Spring mvc 源码剖析

时间: 2022-10-14   |   分类: Spring mvc   | 字数: 1304 字 | 阅读约: 3分钟 | 阅读次数:

Spring mvc 源码剖析

一、DispatcherServlet继承结构

二、重要时机点分析

1.handler方法执行时机

doDispatch方法的 ha.handle方法调用

2.页面渲染时机

jsp页面打断点

调用了 processDispatchResult

Spring处理请求的流程为:

  1. 调⽤getHandler()获取到能够处理当前请求的执⾏链 HandlerExecutionChain(handler+拦截器)
  2. 调⽤getHandlerAdapter();获取能够执⾏1中Handler的适配器
  3. 适配器调⽤Handler执⾏ha.handle(总会返回⼀个ModelAndView对象)
  4. 调⽤processDispatchResult()⽅法完成视图渲染跳转
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.
        //取得处理当前请求的Controller,这⾥也称为Handler,即处理器
        //这⾥并不是直接返回 Controller,⽽是返回 HandlerExecutionChain 请求处理链对象
				//该对象封装了Handler和Inteceptor
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null) {
					// 如果 handler 为空,则返回404
					noHandlerFound(processedRequest, response);
					return;
				}

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

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

				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}

				// Actually invoke the handler.
        //实际处理器处理请求,返回结果视图对象
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				if (asyncManager.isConcurrentHandlingStarted()) {
					return;
				}
				//结果视图对象的处理
				applyDefaultViewName(processedRequest, mv);
				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) {
      //最终会调⽤HandlerInterceptor的afterCompletion ⽅法
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		catch (Throwable err) {
      //最终会调⽤HandlerInterceptor的afterCompletion ⽅法
			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);
				}
			}
		}
	}

三、核心步骤getHandler剖析

遍历handlerMapping,获取能够处理当前请求的执行链

四、核心步骤getHandlerAdapter

遍历各个HandlerAdapter,看哪个Adapter⽀持处理当前Handler

五、ha.handle方法剖析

六、核⼼步骤processDispatchResult⽅法剖析

七、spring mvc九大组件初始化

DispatcherServlet中9个属性(组件)

/** MultipartResolver used by this servlet. */
//多部件解析器
	@Nullable
	private MultipartResolver multipartResolver;

	/** LocaleResolver used by this servlet. */
//国际化解析器
	@Nullable
	private LocaleResolver localeResolver;

	/** ThemeResolver used by this servlet. */
//主题解析器
	@Nullable
	private ThemeResolver themeResolver;

	/** List of HandlerMappings used by this servlet. */
//处理器映射器
	@Nullable
	private List<HandlerMapping> handlerMappings;

	/** List of HandlerAdapters used by this servlet. */
//处理器适配器
	@Nullable
	private List<HandlerAdapter> handlerAdapters;

	/** List of HandlerExceptionResolvers used by this servlet. */
//异常解析器
	@Nullable
	private List<HandlerExceptionResolver> handlerExceptionResolvers;

	/** RequestToViewNameTranslator used by this servlet. */
//默认视力名解析器
	@Nullable
	private RequestToViewNameTranslator viewNameTranslator;

	/** FlashMapManager used by this servlet. */
//flash属性管理组件
	@Nullable
	private FlashMapManager flashMapManager;

	/** List of ViewResolvers used by this servlet. */

//视力解析器
	@Nullable
	private List<ViewResolver> viewResolvers;

初始化时机

//如果还为空,则按照默认策略生成
if (this.handlerMappings == null) {
  this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
  if (logger.isTraceEnabled()) {
    logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
                 "': using default strategies from DispatcherServlet.properties");
  }
}

//从以下配置文件中找
/**
 * Name of the class path resource (relative to the DispatcherServlet class)
 * that defines DispatcherServlet's default strategy names.
 */
private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";

//

#Spring mvc#
QQ扫一扫交流

标题:Spring mvc 源码剖析

作者:古道长亭

声明: 欢迎加群交流!

如有帮助,欢迎多多交流 ^_^

微信打赏

支付宝打赏

zookeeper深入进阶
zookeeper应用场景
  • 文章目录
  • 站点概览
古道长亭

古道长亭

Always remember that your present situation is not your final destination. The best is yet to come.

226 日志
57 分类
104 标签
GitHub Gitee
友情链接
  • 古道长亭的BOOK
  • JAVA学习
标签云
  • Mysql
  • 搜索引擎
  • Mybatis
  • 容器
  • 架构
  • 消息队列
  • Flink
  • Sharding sphere
  • 流处理
  • 缓存
  • 一、DispatcherServlet继承结构
  • 二、重要时机点分析
    • 1.handler方法执行时机
    • 2.页面渲染时机
  • 三、核心步骤getHandler剖析
  • 四、核心步骤getHandlerAdapter
  • 五、ha.handle方法剖析
  • 六、核⼼步骤processDispatchResult⽅法剖析
  • 七、spring mvc九大组件初始化
© 2019 - 2024 京ICP备19012088号-1
0%