- SpringMVC执行流程时序图, 此乃不传之秘。


- SpringMVC执行流程源码分析/源码追踪, 呕心沥血之作。

  • SpringMVC源码版本: 5.1.7.RELEASE

1. 源码分析: Servlet

public interface Servlet {// 初始化方法,构造方法后执行void init(ServletConfig var1);// 每次访问servlet时候执行void service(ServletRequest var1, ServletResponse var2);// 停止服务器时候执行void destroy();
}

2. 源码追踪: FrameworkServlet

protected void service(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());if (httpMethod != HttpMethod.PATCH && httpMethod != null) {super.service(request, response);} else {// 最终都会执行处理请求的方法this.processRequest(request, response);}
}

3. 源码追踪DispatcherServlet

protected void doService(HttpServletRequest request, HttpServletResponse
response) throws Exception {
this.logRequest(request);
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap();
Enumeration attrNames = request.getAttributeNames();
label95:
while(true) {
String attrName;
do {
if (!attrNames.hasMoreElements()) {
break label95;
}
attrName = (String)attrNames.nextElement();
} while(!this.cleanupAfterInclude &&
!attrName.startsWith("org.springframework.web.servlet"));
attributesSnapshot.put(attrName,
request.getAttribute(attrName));
}
}
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE,
this.getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, this.getThemeSource());
if (this.flashMapManager != null) {
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方法
this.doDispatch(request, response);
} finally {
if
(!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() &&
attributesSnapshot != null) {
this.restoreAttributesAfterInclude(request,
attributesSnapshot);
}
}
}
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;
// 根据URI获取到具体的处理器方法 (三大组件之一: 处理器映射器)
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;
}
}
if (!mappedHandler.applyPreHandle(processedRequest,
response)) {
return;
}
// 适配器通过反射调用处理器方法
// 并返回视图和模型
mv = ha.handle(processedRequest, response,
mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
// 如果视图是空采用默认视图
this.applyDefaultViewName(processedRequest, mv);
// 拦截器处理
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);
}
}
}

4. 追踪源码: DispatcherServlet

protected void render(ModelAndView mv, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Locale locale = this.localeResolver != null ?
this.localeResolver.resolveLocale(request) : request.getLocale();
response.setLocale(locale);
String viewName = mv.getViewName();
View view;
if (viewName != null) {
// 根据视图解析器创建视图对象
view = this.resolveViewName(viewName, mv.getModelInternal(),
locale, request);
if (view == null) {
throw new ServletException("Could not resolve view with name '"
+ mv.getViewName() + "' in servlet with name '" + this.getServletName() +
"'");
}
} else {
view = mv.getView();
if (view == null) {
throw new ServletException("ModelAndView [" + mv + "] neither
contains a view name nor a View object in servlet with name '" +
this.getServletName() + "'");
}
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Rendering view [" + view + "] ");
}
try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
// 视图渲染: AbstractView
view.render(mv.getModelInternal(), request, response);
} catch (Exception var8) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Error rendering view [" + view + "]", var8);
}
throw var8;
}
}

5. 追踪源码: AbstractView

public void render(@Nullable Map<String, ?> model, HttpServletRequest
request, HttpServletResponse response) throws Exception {
if (this.logger.isDebugEnabled()) {
this.logger.debug("View " + this.formatViewName() + ", model " +
(model != null ? model : Collections.emptyMap()) +
(this.staticAttributes.isEmpty() ? "" : ", static attributes " +
this.staticAttributes));
}
Map<String, Object> mergedModel = this.createMergedOutputModel(model,
request, response);
this.prepareResponse(request, response);
// 合并视图与数据模型: InternalResourceView
this.renderMergedOutputModel(mergedModel,
this.getRequestToExpose(request), response);
}

6. 追踪源码: InternalResourceView

    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {this.exposeModelAsRequestAttributes(model, request);this.exposeHelpers(request);String dispatcherPath = this.prepareForRendering(request, response);RequestDispatcher rd = this.getRequestDispatcher(request, dispatcherPath);if (rd == null) {throw new ServletException("Could not get RequestDispatcher for [" + this.getUrl() + "]: Check that the corresponding file exists within your web application archive!");} else {if (this.useInclude(request, response)) {response.setContentType(this.getContentType());if (this.logger.isDebugEnabled()) {this.logger.debug("Including [" + this.getUrl() + "]");}rd.include(request, response);} else {if (this.logger.isDebugEnabled()) {this.logger.debug("Forwarding to [" + this.getUrl() + "]");}// 转发页面rd.forward(request, response);}}}

7. 追踪源码: RedirectView


protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) throws IOException
{String targetUrl = this.createTargetUrl(model, request);targetUrl = this.updateTargetUrl(targetUrl, model, request, response);RequestContextUtils.saveOutputFlashMap(targetUrl, request, response);// 重定向地址this.sendRedirect(request, response, targetUrl, this.http10Compatible);
}

联系方式

  • QQ 569284276
  • EM 569284276@qq.com
  • WX 569284276
  • 点击链接加入群聊【8080实验室】: 537950751

SpringMVC的执行流程源码分析?相关推荐

  1. SpringMVC执行流程源码分析

    SpringMVC执行流程源码分析 我们先来看张图片,帮助我们理解整个流程 然后我们开始来解析 首先SpringMVC基于Servlet来运行 那么我们首先来看HttpServletBean这个类 他 ...

  2. springmvc执行过程源码分析

    1:tomcat启动,创建容器过程: 通过load-on-start标签指定1,创建DispatcherServlet对象, DispatcherServlet的父类是继承HttpServlet的,它 ...

  3. SpringBoot2 | SpringBoot启动流程源码分析(一)

    首页 博客 专栏·视频 下载 论坛 问答 代码 直播 能力认证 高校 会员中心 收藏 动态 消息 创作中心 SpringBoot2 | SpringBoot启动流程源码分析(一) 置顶 张书康 201 ...

  4. 【SRIO】5、Xilinx RapidIO核例子工程源码分析

    目录 一.软件平台与硬件平台 二.打开例子工程 三.例子工程详解 3.1 工程概述 3.2 工程结构 3.3 工程分析 四.工程源码分析 3.1 顶层模块srio_example_top.v源码分析 ...

  5. 5.Xilinx RapidIO核例子工程源码分析

    https://www.cnblogs.com/liujinggang/p/10091216.html 一.软件平台与硬件平台 软件平台: 操作系统:Windows 8.1 64-bit 开发套件:V ...

  6. Android系统默认Home应用程序(Launcher)的启动过程源码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  7. 小明分享|8ms平台下工程源码分析

    今天小明为大家分享的是开发工具平台-8ms(www.8ms.xyz)工程源码分析 1.打开"8ms平台",创建工程制作完UI后,选中"编译"一栏,等待结束后,选 ...

  8. 【源码分析】storm拓扑运行全流程源码分析

    [源码分析]storm拓扑运行全流程源码分析 @(STORM)[storm] 源码分析storm拓扑运行全流程源码分析 一拓扑提交流程 一stormpy 1storm jar 2def jar 3ex ...

  9. Android应用程序启动Binder线程源码分析

    Android的应用程序包括Java应用及本地应用,Java应用运行在davik虚拟机中,由zygote进程来创建启动,而本地服务应用在Android系统启动时,通过配置init.rc文件来由Init ...

最新文章

  1. nanoflann库
  2. python请求url非阻塞_Tornado请求中的非阻塞/异步URL获取
  3. Centos下搭建ftp服务器
  4. C/C++程序从编译到最终生成可执行文件的过程分析
  5. C#.NET常见问题(FAQ)-命名空间namespace如何理解
  6. PHP获取浏览器版本号
  7. c++面向对象高级编程 学习七 转换函数
  8. C++函数指针和类成员函数指针
  9. abaqus失效单元删除_[转载]abaqus单元删除的一般方法
  10. STM32/TMS320F2812+W5500硬软件调试总结
  11. IT营最新Node.js入门到实战项目视频教程免费下载
  12. Unity3d知识点
  13. Node连接MySql数据库写模糊查询接口
  14. 07《基于深度学习的车标识别方法研究》学习总结
  15. 看云|专注于文档在线创作、协作、分享和托管
  16. HTTP的请求方法OPTIONS
  17. Mac python 安装信息安全,Pycrypto 出现,C compiler cannot create executablesC编辑器不能创建可执行文件
  18. Dev++ 环境设置C语言关键字显示颜色
  19. 鼠标经过爆炸效果html,jquery鼠标滑过爆炸特效插件
  20. DynamoDB初体验

热门文章

  1. NSSCTF刷题wp——常用编码
  2. 基于FPGA的VGA/LCD显示控制器设计(中)
  3. 谷歌学术导出参考文献(BibTeX)报错 403
  4. [Android]自定义绘制一个简易的音频条形图,附上对MP3音频波形数据的采集与展现
  5. stm32h743外部RAM非字节对齐访问,引起的hard fault
  6. 《《《翻译》》》pointfusion三维包围盒
  7. cf: Ehab and Path-etic MEXs
  8. Ubuntu 使用Thunderbird 加载Exchange类型的邮箱
  9. 穷爸爸富爸爸读书笔记
  10. 12月21日云栖精选夜读 | 推荐:一款分布式的对象存储服务