DispatcherServlet
在springMVC里请求都是由DispatcherServlet 接收,类继承图为
由图可知,他其实本质上是一个Servlet,所以他也会实现Servlet的init(),service(),destroy()等方法(Servlet讲解可参考Servlet文章)
这边介绍DispatcherServlet的init()方法
-
init()
他的init初始化方法其实是在父类HttpServletBean里面写了
-
HttpServletBean.init()
@Override
public final void init() throws ServletException {
// Set bean properties from init parameters.
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
if (!pvs.isEmpty()) {
try {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
if (logger.isErrorEnabled()) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
}
throw ex;
}
}
// Let subclasses do whatever initialization they like.
initServletBean();
}
//接上面代码(省略不重要代码)
@Override
protected final void initServletBean() throws ServletException {
getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'");
try {
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
}
catch (ServletException | RuntimeException ex) {
logger.error("Context initialization failed", ex);
throw ex;
}
}
//接initWebApplicationContext,初始化各种策略
protected void initStrategies(ApplicationContext context) {
//文件上传解析器的接口
initMultipartResolver(context);
//初始化国际化配置的处理类
initLocaleResolver(context);
//初始化主题资源的处理类
initThemeResolver(context);
//初始化处理请求的类,主要负责处理请求调用Controller的处理类。
initHandlerMappings(context);
//初始化HandlerAdapter的适配器
initHandlerAdapters(context);
//初始化异常处理类。
initHandlerExceptionResolvers(context);
//初始化视图转换器,用于直接将请求转换为逻辑视图名。
initRequestToViewNameTranslator(context);
//初始化视图解析器,定义了如何通过view 名称来解析对应View实例的行为
initViewResolvers(context);
//初始化Flash Map,提供一个请求存储属性,可供其它请求使用。
initFlashMapManager(context);
}
-
HttpServletBean.init()时序图
dispatchServlet流程处理
流程图
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
//先判断是否Multipart类型的请求。如果是则通过multipartResolver解析request
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 通过getHandler方法找到从HandlerMapping,然后找到该请求对应的handler,如果没有找到对应的handler则抛出异常。
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 通过getHandlerAdapter方法找到handler对应的HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
//如果有拦截器,执行拦截器preHandler方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 真正HandlerAdapter执行handle方法处理请求,返回ModelAndView。
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
//如果有拦截器,执行拦截器postHandle方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
//然后调用processDispatchResult方法处理请求结果,封装到response中。
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
网友评论