DisPatcherServlet(前端控制器)作为Spring MVC的核心组件之一,DispatcherServlet的调用过程是我们必须要掌握的。本文就Spring MVC DispatcherServlet调用过程展开详细的解答。
一、调用HandleMapping得到handler
定义: 请求路径-处理过程映射管理
打个比方就是根据你的http请求的路径得到可以处理的handler(你的Controller方法)
/**
* Interface to be implemented by objects that define a mapping between
* requests and handler objects.
*/
public interface HandlerMapping {
//根据request获取处理链
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
过程概括:
1.获取所有object子类
2.根据条件过滤出handle处理类
3.解析handle类中定义的处理方法
4.保存解析得出的映射关系
二、调用HandleAdapter执行handle过程(参数解析 过程调用)
定义: 根据HandlerMapping.getHandler()得到的Handler信息,对http请求参数解析并绑定。
先看一下HandlerAdapter的接口定义:
public interface HandlerAdapter {
//判断是否支持该handler类型的解析
boolean supports(Object handler);
//参数解析 并调用handler完成过程调用
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
//用于处理http请求头中的last-modified
long getLastModified(HttpServletRequest request, Object handler);
}
过程概括:
1.装载带有ControllerAdvices注解的对象
2.装载ArgumentResolvers(默认+自定义)
3.装载InitBinderArgumentResolvers(默认+自定义)
4.装载ReturnValueHandlers(默认+自定义)
看一下HandlerMethodReturnValueHandler接口和HandlerMethodArgumentResolver接口
//参数解析器
public interface HandlerMethodArgumentResolver {
//判断是否支持该参数的解析(根据类型,注解等)
boolean supportsParameter(MethodParameter parameter);
//对参数进行解析 得到解析结果
Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception;
}
//返回值解析器
public interface HandlerMethodReturnValueHandler {
//判断是否支持该返回值的解析(根据类型,注解等)
boolean supportsReturnType(MethodParameter returnType);
//对返回值进行解析
void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}
三、调用ViewResolver进行视图解析
DispatcherServlet调用HandlerAdapter过程
//1.调用support()方法判断是否支持改handler的解析
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 如果是Get或Head请求 调用getLastModified()获取上次更新时间
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
//如果小于浏览器缓存更新时间 则直接返回 浏览器使用本地缓存
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
四、渲染视图
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
//1.调用handlerMapping获取handlerChain
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// 2.获取支持该handler解析的HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
...
// 3.使用HandlerAdapter完成handler处理
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
// 4.视图处理(页面渲染)
applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
...
}
上面就是Spring MVC 中DispatcherServlet调用的整个过程,事实上,Spring MVC框架的工作原理正是其核心组件调用其他组件工作的过程。对于这一点,本站中的Spring MVC视频教程中有更多的讲解和全面的分析,感兴趣的小伙伴可以仔细观看学习。
QCode09-04 14:38
Code大师09-04 14:50
不写代码你养我啊08-23 11:14
不写代码你养我啊09-17 18:02
要学习了06-18 18:13