DispatcherServlet最全详解
DispatcherServlet族谱
一、语言总结
1.DispatcherServlet初始化
1.servlet初始化会调用init()方法,
2.GenericServlet重写了方法调用自己重写的init()方法,
3.HttpServlet没有重写方法直到HttpServletBean()重写了init方法并调用initServletBean
(大致意思是将配置参数映射到该servlet的bean属性上,以及调用子类初始化 ),
4.FrameworkServlet重写了initServletBean()方法 方法内部 调用了initWebApplicationContext()进行了SpringMVC容器初始化,
然后调用onRefresh()进行初始化
5.DispatcherServlet重写onRefresh()方法继续套娃调用initStrategies()方法实现容器刷新策略
初始化完成之后将ioc容器共享到应用域中
**扩展内容:**
【 4.1 initWebApplicationContext()内部调用了createWebApplicatioContext()方法创建WebApplicationContext
4.2 在createWebApplicationContext()方法中用反射创建了ConfigurableWebApplicationContext容器
然后设置了它的环境以及它的父容器(将SpringIOC容器设置为SpringMVCIOC的父容器)然后将容器返回
扩展:共享名称 == 全类名 + .CONTEXT. +DispatcherServlet】
2.DispatcherServlet调用组建处理请求
1.servlet处理请求会调用service方法 继续等着儿子去重写方法
2. HttpServlet这里重写以及重载了方法 先是重写将参数向下转型然后调用重载的Servlet()方法
3. FrameworkServlet重写了方法多加了一个判断PATCH请求 如果是继续调用它爷爷HttpServlet的方法
如果请求不是PATCH则调用自己重写的方法processRequest() ,processRequest() 调用 doService()方法,
但是doService()又是抽象方法未实现功能所以继续找儿子
4.DispatcherServlet继承doService()最终获得ModelAndView对象
二、DispatcherServlet初始化
1.servlet初始化会调用init方法
从servlet开始
servlet初始化会调用init方法
2. servlet子类GenericServlet重写了方法调用自己重写的init方法
servlet子类GenericServlet重写了方法调用自己重写的init方法
3.HttpServletBean重写了init方法
HttpServlet没有重写方法直到HttpServletBean重写了init方法
大致意思是将配置参数映射到该servlet的bean属性上,以及调用子类初始化
然后写了一个initServletBean抽象方法留给子类
4.FrameworkServlet重写了initServletBean方法
FrameworkServlet重写了initServletBean方法 方法内部 调用了initWebApplicationContext
进行了SpringMVC容器初始化
创建WebApplicationContext过程
调用createWebApplicatioContext方法创建WebApplicationContext
继续套娃调用
在createWebApplicationContext方法中用反射创建了ConfigurableWebApplicationContext容器
然后设置了它的环境以及它的父容器(将SpringIOC容器设置为SpringMVCIOC的父容器)然后将容器返回
这里进行了数据共享 将WebApplicationContext在应用域进行了共享
共享应用域的名称
共享名称 == 全类名 + .CONTEXT. +DispatcherServlet
容器刷新 初始化
继续让儿子去实现
6.DispatcherServlet重写方法继续套娃调用initStrategies 实现容器刷新策略
初始化完成之后将ioc容器共享到应用域中
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context); //初始化文件上传解析器
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context); //初始化处理器映射器
initHandlerAdapters(context); //初始化处理器适配器
initHandlerExceptionResolvers(context); //初始化异常处理器
initRequestToViewNameTranslator(context);
initViewResolvers(context); //初始化视图解析器
initFlashMapManager(context);
}
二、DispatcherServlet调用组建处理请求
1.servlet处理请求会调用service方法 继续等着儿子去重写方法
老样子从servlet开始
2.GenericServlet继承了并未重写 继续往下找儿子
3.HttpServlet这里重写以及重载了方法 先是重写将参数向下转型然后调用重载的Servlet方法
4.重载的Servlet方法获取请方式然后进行调用
5.FrameworkServlet重写了方法多加了一个判断PATCH 然后继续调用它爷爷HttpServlet的方法
(HttpServletBean是没有对方法进行重写的)
如果请求不是PATCH则调用自己重写的方法processRequest
这里处理请求的方法是继续调用doService 但是doService又是抽象方法未实现功能所以继续找儿子
6.DispatcherServlet继承doService
doService方法
doService这里往请求域一顿扔垃圾继续调用doDispatch进行统一处理请求和响应
doDispatch方法
后面我会更新MVC执行流程
因为我本身就是自学的小白码的很差劲 我会努力做的更好
希望能对学到MVC的朋友们有所帮助 (点个赞吧码了挺久的。)
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;
Exception dispatchException = null;
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
mappedHandler = this.getHandler(processedRequest);
/* mappedHandler:调用链 包含handler、interceptorList、interceptorIndex
handler:浏览器发送的请求所匹配的控制器方法
interceptorList:处理控制器方法的所有拦截器集合
interceptorIndex:拦截器索引,控制拦截器afterCompletion()的执行 */
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;
}
}
// 调用拦截器的preHandle()
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 由处理器适配器调用具体的控制器方法,最终获得ModelAndView对象
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, mv);
// 调用拦截器的postHandle()
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);
}
}
}