文章目录
1.SpringMVC 介绍
SpringMVC 是一款基于 Spring 框架的 MVC 框架,它采用了 各种设计模式,包括 FrontController、Dispatcher、ViewHelper 等。同时,SpringMVC 与 Spring 框架集成紧密,可以很方便地与其他 Spring 组件(如 Spring Security)进行整合。
2.SpringMVC 执行流程
SpringMVC 的执行流程可以分为以下几个步骤:
3.组件介绍
HandlerMapping
HandlerMapping 用于映射请求 URL 到对应的处理器(Handler)。在 SpringMVC 中,常用的 HandlerMapping 实现包括 BeanNameUrlHandlerMapping、RequestMappingHandlerMapping 等。
HandlerAdapter
HandlerAdapter 用于执行处理器(Handler),它将处理器的执行与前后端的交互分离开来。在 SpringMVC 中,常用的 HandlerAdapter 实现包括 RequestMappingHandlerAdapter、SimpleControllerHandlerAdapter 等。
Handler
Handler 即处理器,它是处理请求的核心组件,通常由 Controller 实现类来充当。处理器可以调用 Service 层、DAO 层等其他组件来获取数据和执行业务逻辑,最终返回一个 ModelAndView 对象。
ModelAndView
ModelAndView 是处理器返回的结果对象,它包含了视图名和需要在视图中渲染的模型数据。
ViewResolver
ViewResolver 用于将视图名解析为对应的视图对象(View)。在 SpringMVC 中,常用的 ViewResolver 实现包括 InternalResourceViewResolver(用于解析 JSP 视图)、FreeMarkerViewResolver(用于解析 FreeMarker 模板)等。
View
View 即视图,它用于渲染模型数据,最终生成响应内容。在 SpringMVC 中,常用的 View 实现包括 JstlView(用于渲染 JSP 视图)、FreeMarkerView(用于渲染 FreeMarker 模板)等。
4.源码解析
DispatcherServlet最终继承了HttpServlet, 继承关系如下源码
public class DispatcherServlet extends FrameworkServlet
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware
首先进入的就是doService方法
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();
label116:
while(true) {
String attrName;
do {
if (!attrNames.hasMoreElements()) {
break label116;
}
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);
}
RequestPath previousRequestPath = null;
if (this.parseRequestPath) {
previousRequestPath = (RequestPath)request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE);
ServletRequestPathUtils.parseAndCache(request);
}
try {
this.doDispatch(request, response);
} finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() && attributesSnapshot != null) {
this.restoreAttributesAfterInclude(request, attributesSnapshot);
}
if (this.parseRequestPath) {
ServletRequestPathUtils.setParsedRequestPath(previousRequestPath, request);
}
}
}
2.然后调用了 doDispatch(request, response) . 调用 getHandler 查找处理器映射器
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
Iterator var2 = this.handlerMappings.iterator();
while(var2.hasNext()) {
HandlerMapping mapping = (HandlerMapping)var2.next();
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
3.返回了处理器执行链,HandlerExecutionChain(处理器执行链)包含了一个或多个Interceptor拦截器和一个Handler处理器
4. DispatcherServlet查找并返回处理器适配器
getHandlerAdapter源码
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
Iterator var2 = this.handlerAdapters.iterator();
while(var2.hasNext()) {
HandlerAdapter adapter = (HandlerAdapter)var2.next();
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
5.执行处理方法,调用Handler处理器(又名Controller),6. 返回ModelAndView
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
//调用拦截器
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//调用Handler处理器(又名Controller),返回ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
Handler接口
Handler实现,最终转成了Controller,并且调用了handleRequest方法
handleRequest接口
handleRequest实现,返回的ModelAndView
@Nullable
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
response.setHeader("Allow", this.getAllowHeader());
return null;
} else {
this.checkRequest(request);
this.prepareResponse(response);
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized(mutex) {
return this.handleRequestInternal(request, response);
}
}
}
return this.handleRequestInternal(request, response);
}
}
DispatchServlet 继续调用了processDispatchResult
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
8.调用render方法
9.DispatchServlet中的 render方法中,视图解析器返回View
view.render 调用了 renderMergedOutputModel 进行输出
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);
this.renderMergedOutputModel(mergedModel, this.getRequestToExpose(request), response);
}
调用了RequestDispatcher 的 forward 把数据响应出去
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);
}
}
}
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 {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(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);
}
}
}
参考了 SpringMVC执行流程,并补充了源码解析