组件介绍
DispatcherServlet(前端控制器):
-----------核心,接收用户请求,进行请求分发,处理响应结果HandlerMapping(处理器映射器):
-----------1.根据请求的url对应的处理器。 2. 返回处理器执行链(包含Handler对象以及它对应的拦截器)
HandlerAdapter(处理器适配器):
----------- 调用处理器的处理请求方法,因为实现Controller有不同的方式,所以需要获取对应的适配器 适配器模式
Handler(处理器,又名Controller):
-----------1.根据请求执行业务逻辑 2. 返回ModelAndView对象
ViewResolver(视图解析器):
-----------1.处理视图信息,将逻辑视图转化为真正的物理视图 2. 返回View对象
流程图
源码解析
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
//记录日志
logRequest(request);
//属性赋值
Map<String, Object> attributesSnapshot = null;
...
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
...
try {
//分发请求,doDispatch方法中是核心逻辑
doDispatch(request, response);
}
finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
}
//分发请求 重要!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 获取处理器执行链
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 传入处理器执行链中的处理器,获取一个合适的适配器。因为有很多不同的处理器实现方式,需要找到适合的适配器进行调用
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;
}
}
//调用拦截器
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 使用合适的处理器适配器调用处理器,此时会跳转到我们自己写的Controller的方法中,执行后返回ModelAndView对象
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
//拦截器
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
//调用视图解析器处理ModelAndView对象
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
//返回处理器执行链
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
//遍历处理器映射器
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
//如果该处理器映射器能返回处理器执行链,则返回
if (handler != null) {
return handler;
}
}
}
return null;
}
//返回适合处理这个handler的适配器,返回后,这个适配器用于调用处理器的方法
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
//遍历适配器
for (HandlerAdapter adapter : this.handlerAdapters) {
//如果找到一个支持该handler的适配器,则返回
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");
}
执行流程总结
1、浏览器向web服务器(如tomcat)发送一个http请求,web服务器对http请求进行解析。 如果解析后的URL地址如果匹配了Web.xml中的servlet-mapping配置 ,就将请求交给DispatcherServlet处理。
/
2、DispatcherServlet接收到这个请求后,doService方法会接收到封装好的两个参数HttpServletRequest和 HttpServletResponse 。
doService(HttpServletRequest request,HttpServletResponse response)
在doService方法中,先进行日志记录 logRequest(request) ,然后对这个request请求填充一些属性,之后将处理过的request对象传入doDispatch方法中,执行doDispatch方法进行分发请求。
/
doDispatch方法中会调用getHandler方法,这个方法内部,其实是一个对handlerMappings的for循环,每个handlerMapping都通过getHandler方法返回HandlerExecutionChain对象,如果这个对象不为null,说明获取成功,将得到的处理器执行链return给DispatcherServlet。在处理器执行链中包含Handler对象以及它对应的拦截器。
/
3、DispatcherServlet将得到的处理器执行链中的Handler对象传入getHandlerAdapter方法中,
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler())
这个方法其实也是个对handlerAdapters的for循环,如果某个handlerAdapters适配传入的Handler对象,则返回该handlerAdapters
判断是否适配:supports方法里其实只是通过 instanceof进行判断
SimpleServletHandlerAdapter: handler instanceof Servlet
HttpRequestHandlerAdapter: handler instanceof HttpRequestHandler
/
4、开始执行Handler
ha.handle(processedRequest, response, mappedHandler.getHandler())
Handler执行完毕后返回一个ModelAndView对象给DispatcherServlet。
/
6、这个ModleAndView只是一个逻辑视图,并不是真正的视图,DispatcherServlet通过ViewResolver视图解析器将逻辑视图转化为真正的物理视图(通俗理解为将视图名称补全,如加上路径前缀,加上.jsp后缀,能指向实际的视图)。
/
7、DispatcherServlet通过Model将ModelAndView中得到的处数据解析后用于渲染视图。将得到的最终视图View对象通过http响应返回客户端。