一、重点方法:
类:DispatcherServlet
方法:
protected void initStrategies(ApplicationContext context) {
this.initMultipartResolver(context);
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
this.initHandlerExceptionResolvers(context);
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
protected void doDispatch(HttpServletRequest request){
...
}
二、doDispatch() 解析
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
// 为true代表此请求是文件上传请求
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;
}
// ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
// view
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);
}
}
}
1,WebAsyncUtils.getAsyncManager(request)
/**
请求体获取 WEB_ASYNC_MANAGER_ATTRIBUTE 属性
为空则设置,虽然设置的是空的构造方法,但是有不少默认值
如果想断点看看,可以用执行方法先后的请求体比较 Attribute
*/
public static WebAsyncManager getAsyncManager(ServletRequest servletRequest) {
WebAsyncManager asyncManager = null;
Object asyncManagerAttr = servletRequest.getAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE);
if (asyncManagerAttr instanceof WebAsyncManager) {
asyncManager = (WebAsyncManager)asyncManagerAttr;
}
if (asyncManager == null) {
asyncManager = new WebAsyncManager();
servletRequest.setAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE, asyncManager);
}
return asyncManager;
}
/**
gpt解析
taskExecutor是一个java.util.concurrent.Executor类型
的对象,用于执行异步处理任务
concurrentResult和callableInterceptors分别用于保存
并发结果和异步处理的拦截器
deferredResultInterceptors用于保存
DeferredResult异步处理的拦截器
*/
WebAsyncManager() {
this.taskExecutor = DEFAULT_TASK_EXECUTOR;
this.concurrentResult = RESULT_NONE;
this.callableInterceptors = new LinkedHashMap();
this.deferredResultInterceptors = new LinkedHashMap();
}
三、this.checkMultipart(request);
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
// isMultipart(request)断点进去看看怎么判断的
// 两个实现类,都打上断点就知道走哪个了
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
if (DispatcherType.REQUEST.equals(request.getDispatcherType())) {
this.logger.trace("Request already resolved to MultipartHttpServletRequest, e.g. by MultipartFilter");
}
} else if (this.hasMultipartException(request)) {
this.logger.debug("Multipart resolution previously failed for current request - skipping re-resolution for undisturbed error rendering");
} else {
try {
return this.multipartResolver.resolveMultipart(request);
} catch (MultipartException var3) {
if (request.getAttribute("javax.servlet.error.exception") == null) {
throw var3;
}
}
this.logger.debug("Multipart resolution failed for error dispatch", var3);
}
}
return request;
}
断点看,请求体没看到content-type啊
public boolean isMultipart(HttpServletRequest request) {
return StringUtils.startsWithIgnoreCase(request.getContentType(), this.strictServletCompliance ? "multipart/form-data" : "multipart/");
}
request.getContentType()点进去看,断点走一圈
public MessageBytes contentType() {
if (this.contentTypeMB == null) {
this.contentTypeMB = this.headers.getValue("content-type");
}
return this.contentTypeMB;
}
四、HandleMapping --> getHandler --> HandlerExecutionChain
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 此处看 this.initHandlerMappings(context);
if (this.handlerMappings != null) {
Iterator var2 = this.handlerMappings.iterator();
while(var2.hasNext()) {
HandlerMapping mapping = (HandlerMapping)var2.next();
// handler包含interceptorList和handler接口
// aop的拦截器mapping.getHandler(request)就是需要在此处加入,
// MVC一个大组件 HandlerExecutionChain
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
五种HandlerMapping
套娃严重,直接看结果
五、HandlerExecutionChain,Handler --> getHandlerAdapter --> HandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
Iterator var2 = this.handlerAdapters.iterator();
while(var2.hasNext()) {
HandlerAdapter adapter = (HandlerAdapter)var2.next();
// 选个实现类 SimpleControllerHandlerAdapter 看下就行
// 看了此方法明了,处理成控制层可以处理的接口
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");
}
SimpleControllerHandlerAdapter
public boolean supports(Object handler) {
return handler instanceof Controller;
}
六、ModelAndView
HandlerAdapter --> AbstractHandlerMethodAdapter
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
Object result;
try {
//获取数据绑定工厂
WebDataBinderFactory binderFactory = this.getDataBinderFactory(handlerMethod);
//获取模型工厂
ModelFactory modelFactory = this.getModelFactory(handlerMethod, binderFactory);
//创建可调用的处理方法
ServletInvocableHandlerMethod invocableMethod = this.createInvocableHandlerMethod(handlerMethod);
if (this.argumentResolvers != null) {
//设置参数解析器
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
if (this.returnValueHandlers != null) {
//设置返回值处理器
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
//设置数据绑定工厂
invocableMethod.setDataBinderFactory(binderFactory);
//设置参数名发现器
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
//创建视图模型容器
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
//添加所有的FlashMap属性
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
//初始化模型 -- 看下参数
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
//设置在重定向时是否忽略默认模型
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
//创建异步Web请求
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
//设置异步请求超时时间
asyncWebRequest.setTimeout(this.asyncRequestTimeout);
//获取Web异步管理器
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
//设置任务执行器
asyncManager.setTaskExecutor(this.taskExecutor);
//设置异步Web请求
asyncManager.setAsyncWebRequest(asyncWebRequest);
//注册Callable拦截器
asyncManager.registerCallableInterceptors(this.callableInterceptors);
//注册DeferredResult拦截器
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
//如果存在并发结果
if (asyncManager.hasConcurrentResult()) {
//获取并发结果
result = asyncManager.getConcurrentResult();
//获取视图模型容器
mavContainer = (ModelAndViewContainer)asyncManager.getConcurrentResultContext()[0];
//清除并发结果
asyncManager.clearConcurrentResult();
LogFormatUtils.traceDebug(this.logger, (traceOn) -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);
return "Resume with async result [" + formatted + "]";
});
//包装并发结果
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
//调用处理方法
invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);
//如果没有并发处理启动
if (!asyncManager.isConcurrentHandlingStarted()) {
//获取视图模型
ModelAndView var15 = this.getModelAndView(mavContainer, modelFactory, webRequest);
return var15; //返回视图模型
}
result = null;
} finally {
webRequest.requestCompleted();
}
return (ModelAndView)result;
}
七、view
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()) {
// 点进去
this.render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
} else if (this.logger.isTraceEnabled()) {
this.logger.trace("No view rendering, null ModelAndView returned.");
}
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
}
}
}
/**
* Render the given ModelAndView.
* This is typically used to render a page with a template and model data.
* This method will resolve the view name and create a view to render it.
* If the ModelAndView contains a specific status code, it will set the response status accordingly.
*
* @param mv the ModelAndView to render
* @param request current HTTP request
* @param response current HTTP response
* @throws Exception if view rendering or response handling fails
*/
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("无法在名为 '" + this.getServletName() + "' 的servlet中解析视图名称为 '" + mv.getViewName() + "' 的视图");
}
} else {
// 若视图名称为null,获取视图对象
view = mv.getView();
if (view == null) {
throw new ServletException("ModelAndView [" + mv + "] 中既不包含视图名称,也不包含视图对象在名为 '" + this.getServletName() + "' 的servlet中");
}
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("正在渲染视图 [" + view + "] ");
}
try {
// 设置响应状态码
if (mv.getStatus() != null) {
request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, mv.getStatus());
response.setStatus(mv.getStatus().value());
}
// 渲染视图
view.render(mv.getModelInternal(), request, response);
} catch (Exception var8) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("渲染视图 [" + view + "] 出错", var8);
}
throw var8;
}
}