目录
六、Spring容器与SpringMVC容器关系分析(暂定)
这篇文章从源码的角度去分析MVC的执行流程,通过阅读源码能够更清晰的了解MVC的执行流程,这也是我自己的一种学习方法,学习+输出能够帮助自己掌握的更牢固,希望大家一起成长. 【基于源码5.0.4】
一、SpringMVC执行流程
二、SpringMVC源码剖析
根据执行流程查看源码步骤(xml方式)
//Controller层
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
mv.setViewName("success");
mv.addObject("hello","yoo");
return mv;
}
}
通过断点进入到DispatcherServlet前端控制器的doService方法
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
//此处省略部分。。。
try {
/*
* 进入到DispatcherServlet前端控制器
* 执行doService方法,并在其中调用doDispatch方法
*/
this.doDispatch(request, response);
} finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() && attributesSnapshot != null) {
this.restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
【非常重要】doDispatch方法中涉及到相当多的步骤,根据执行流程图步骤查看
步骤3: 返回处理器执行链
步骤4: 处理器适配器
步骤5: 处理器
步骤6: 返回ModelAndView 对象
步骤7: 返回ModelAndView对象给DispatcherServlet前端控制器
步骤8: 执行视图解析
步骤9: 返回视图解析后的对象
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;
/*
* 步骤3
* 调用getHandler()方法,返回执行链
* 进入到getHandler看看具体逻辑代码
*/
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
/*
* 步骤4
* 调用getHandlerAdapter()方法,获取处理器适配器
*/
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 (this.logger.isDebugEnabled()) {
this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
/*
* 调用拦截器
*/
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
/*
* 步骤5,步骤6,步骤7
* 调用处理器适配器的handler()方法,获取处理器
* 并返回ModelAndView
*/
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);
}
/*
* 步骤8
* 执行视图解析
*/
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);
}
}
}
步骤3相关部分: 断点进入getHandler()方法查看具体代码(返回HandlerExecutionChain )
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
Iterator var2 = this.handlerMappings.iterator();
while(var2.hasNext()) {
/*
* 先获取处理器映射器
*/
HandlerMapping hm = (HandlerMapping)var2.next();
if (this.logger.isTraceEnabled()) {
this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + this.getServletName() + "'");
}
/*
* request: 根据用户请求
* 调用处理器映射器中的getHandler()方法,获取执行链
* 这里需要注意,xml方式的HandlerMapping的实例是->BeanNameUrlHandlerMapping
*/
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
=======================================================
/*
* HandlerExecutionChain 类
* 包含handle以及interceptors
*/
public class HandlerExecutionChain {
private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
private final Object handler;
@Nullable
private HandlerInterceptor[] interceptors;
@Nullable
private List<HandlerInterceptor> interceptorList;
private int interceptorIndex;
}
=========================================================
//调用处理器映射器中的getHandler()方法
@Nullable
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = this.getHandlerInternal(request);
if (handler == null) {
handler = this.getDefaultHandler();
}
if (handler == null) {
return null;
} else {
if (handler instanceof String) {
String handlerName = (String)handler;
handler = this.obtainApplicationContext().getBean(handlerName);
}
/*
* 这里对HandlerExecutionChain进行封装(不再深究)
* 然后返回HandlerExecutionChain对象
*/
HandlerExecutionChain executionChain = this.getHandlerExecutionChain(handler, request);
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = this.getCorsConfiguration(handler, request);
CorsConfiguration config = globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig;
executionChain = this.getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
}
步骤4相关部分: 调用getHandlerAdapter()获取处理器适配器
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
Iterator var2 = this.handlerAdapters.iterator();
while(var2.hasNext()) {
/*
* 根据类型获取具体的适配器类型
* 此类型为xml,因此获取的适配器类型为 -> SimpleControllerHandlerAdapter
*/
HandlerAdapter ha = (HandlerAdapter)var2.next();
if (this.logger.isTraceEnabled()) {
this.logger.trace("Testing handler adapter [" + ha + "]");
}
if (ha.supports(handler)) { //ha: SimpleControllerHandlerAdapter@4662
return ha;
}
}
}
throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
步骤5相关部分: 调用处理器适配器的handle()方法获取处理器
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return ((Controller)handler).handleRequest(request, response);
}
步骤8相关部分:
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
boolean errorView = false;
if (exception != null) {
if (exception instanceof ModelAndViewDefiningException) {
this.logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException)exception).getModelAndView();
} else {
Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
mv = this.processHandlerException(request, response, handler, exception);
errorView = mv != null;
}
}
if (mv != null && !mv.wasCleared()) {
/*
* 调用render()方法进行解析视图操作
*/
this.render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + this.getServletName() + "': assuming HandlerAdapter completed request handling");
}
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
}
}
}
=================================================================
//具体的本类的render()方法
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.isDebugEnabled()) {
this.logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + this.getServletName() + "'");
}
try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
/*
* 步骤10
* 将解析后的视图填充进view中渲染视图
*/
view.render(mv.getModelInternal(), request, response);
} catch (Exception var8) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" + this.getServletName() + "'", var8);
}
throw var8;
}
}
====================================================
//view中的render方法
public void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Rendering view with name '" + this.beanName + "' with model " + model + " and static attributes " + this.staticAttributes);
}
Map<String, Object> mergedModel = this.createMergedOutputModel(model, request, response);
this.prepareResponse(request, response);
/*
* 将解析的视图数据填充进View中
* 进入其中的forward()方法,返回给客户端
*/
this.renderMergedOutputModel(mergedModel, this.getRequestToExpose(request), response);
}
关于SpringMVC的执行流程源码大概就是这样