- SpringMVC执行流程时序图, 此乃不传之秘。
- SpringMVC执行流程源码分析/源码追踪, 呕心沥血之作。
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 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 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 mergedModel = this.createMergedOutputModel(model,
request, response);
this.prepareResponse(request, response);
// 合并视图与数据模型: InternalResourceView
this.renderMergedOutputModel(mergedModel,
this.getRequestToExpose(request), response);
}
6. 追踪源码: InternalResourceView
protected void renderMergedOutputModel(Map 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 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);
}