- DispatcherServlet#doService
- doDispatch(request, response)
- checkMultipart(request)
- getHandler(processedRequest)
- getHandlerAdapter(mappedHandler.getHandler())
- mappedHandler.applyPreHandle(processedRequest, response)
- ha.handle(processedRequest, response, mappedHandler.getHandler())
- mappedHandler.applyPostHandle(processedRequest, response, mv)
- processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException)
- doDispatch(request, response)
在Spring与SpringMVC整合的博客中(https://www.yuque.com/zhanyifan-rkxpe/grf7g5/ei9r2u) 我们提到,最终Spring与SpringMVC整合完成之后,会创建出一个DispatcherServlet,并将他添加到Servlet容器中。都知道,Servlet在处理请求的时候,会调用父类的service()方法,最终调用到doService中。所以,我们就从doService方法开始看起。
DispatcherServlet#doService
其中,最关键是,调用了this.doDispatch(request, response)方法
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 {
this.doDispatch(request, response);
} finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() && attributesSnapshot != null) {
this.restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
doDispatch(request, response)
主要的流程包括如下的几步:
- processedRequest = checkMultipart(request) 判断当前的请求是否是上传文件的请求
- mappedHandler = getHandler(processedRequest) 根据当前请求,获取到对应的处理器执行链
- HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()) 根据处理器执行链中的处理器,找到对应的适配器(Handler有多种实现方式,采用适配器的模式进行适配)
- mappedHandler.applyPreHandle(processedRequest, response) 调用处理器执行链中的拦截器链的before方法,如果拦截器链全部返回true,则进入第5步,执行目标handler,否则,进去第8步,执行拦截器的afterCompletion方法
- mv = ha.handle(processedRequest, response, mappedHandler.getHandler()) 拦截通过,进入处理器执行目标方法,返回ModelAndView
- mappedHandler.applyPostHandle(processedRequest, response, mv) 执行处理器执行链中的after方法
- processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException) 最终,处理执行结果,根据执行结果返回View或者返回json数据。
- 如果上面7步,执行中发生了异常,或者执行拦截器返回了false的话,则会执行 triggerAfterCompletion(processedRequest, response, mappedHandler, ex)。执行拦截器的afterCompletion方法
checkMultipart(request)
检查是否是一个上传文件的请求,如果是,使用multipartResolver 进行request的解析。
getHandler(processedRequest)
通过当前的请求,找到对应的处理器映射器(HandlerMapping),通过对应的HandlerMapping找到对应的处理器执行链
其中getHandlerInternal是一个抽象方法,根据不同的请求,有不同的实现类,例如通过@RequestMapping来实现Controller的话,是采用RequestMappingHandlerMapping来获取对应的Handler等。
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 首先呢,根据当前请求,获取到对应的Handler
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
// 然后根据handler以及Reuqest,找出对应的处理器执行链
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
logger.debug("Mapped to " + executionChain.getHandler());
}
// 处理跨域
if (hasCorsConfigurationSource(handler)) {
CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
config = (config != null ? config.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
getHandlerAdapter(mappedHandler.getHandler())
根据Servlet启动时,预先加载的处理器适配器,调用supports方法,判断是否适配,如果适配,返回这个适配器
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
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");
}
具体的对应关系如下
HttpRequestHandlerAdapter | 适配实现了HttpRequestHandler |
---|---|
SimpleControllerHandlerAdapter | 适配实现了Controller |
AbstractHandlerMethodAdapter | 适配标注了@Controller |
mappedHandler.applyPreHandle(processedRequest, response)
从头开始循环所有的拦截器,调用其中的preHandle方法,如果其中一个拦截器返回了false,则if条件成立,将会执行triggerAfterCompletion方法,返回false,在doDispatch方法中,将会直接return。
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
ha.handle(processedRequest, response, mappedHandler.getHandler())
调用 getHandlerAdapater 中所返回的处理器适配器中的handle方法,内部
适配器 | 所调用的方法 |
---|---|
HttpRequestHandlerAdapter | HttpRequestHandler#handleRequest |
SimpleControllerHandlerAdapter | Controller#handleRequest |
AbstractHandlerMethodAdapter | @Controller类中标注了@RequestMapping的方法 |
mappedHandler.applyPostHandle(processedRequest, response, mv)
调用拦截器的后置方法,这里,采用从后往前遍历的方式,达到一种,类似于递归一样的效果。最先执行preHandle的方法,最后执行postHandle方法。
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
}
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException)
处理Handler返回的结果
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) {
logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException) exception).getModelAndView();
}
else {
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
}
}
// 进行视图的渲染,如果ModelAndView不为null的话
// Did the handler return a view to render?
if (mv != null && !mv.wasCleared()) {
// 渲染视图
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No view rendering, null ModelAndView returned.");
}
}
if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Concurrent handling started during a forward
return;
}
// 最终,调用拦截器的afterCompletion方法
if (mappedHandler != null) {
// Exception (if any) is already handled..
mappedHandler.triggerAfterCompletion(request, response, null);
}
}
render(mv, request, response) ->
view.render(mv.getModelInternal(), request, response) -> AbstractView
@Override
public void render(@Nullable Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("View " + formatViewName() +
", model " + (model != null ? model : Collections.emptyMap()) +
(this.staticAttributes.isEmpty() ? "" : ", static attributes " + this.staticAttributes));
}
// 从Model中获取响应的数据
Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
prepareResponse(request, response);
// 渲染响应的数据
renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
}