Spring MVC
Spring MVC流程
- 用户发起请求到DispathcherServlet(中央调度器)
- 中央调度器接收倒请求后调用handlerMapping映射器,handlerMapping通过url获取HandlerExecutionChain对象,里面包含了handler(handdlerMethod Controller的方法)、handlerInterceptor;
- 中央调度器调用handlerAdapter,通过适配器模式获取适应的处理器,执行不同的handler(执行Controller的方法);
- handler执行完给handlerAdapter返回 ModelAndView;
- handlerAdapter将ModelAndView返回给 中央调度器 ;
- 中央调度器 将ModelAndView给ViewResloer进行视图解析;
- ViewResloer将解析后的View返回给中央调度器;
- 中央调度器将model填充到View中进行视图渲染,然后返回给用户;
- DispatcherServlet:中央调度器, 接受请求,响应结果,作为其他组件的转发者,降低其他组件的耦合度;
- HandlerMapping:处理器映射器, 根据url去获取handler(可以理解为通过url获取指定Controller的Method);
- HandlerAdapter:处理器 ,基础的有RequestMappingHandlerAdapter(执行@RequestMapping的修饰的方法),HandlerFunctionAdapter(用于处理实现HandlerFunction接口的实现类),HttpRequestHandlerAdapter(用于处理实现HttpRequestHandler接口的实现类,大多数用于静态资源),SimpleControllerAdapter(用于处理实现HttpRequestHandler接口的实现类);
- ViewResolver:视图解析器 ,根据逻辑视图名解析成真正的视图;
组件
- handlerMapping:根据url找到响应的处理器,常用的是找到Method
- handlerAdapter:找到handler适合的类型,并执行handler
- handlerExceptionResolver:处理handler产生的异常
- requestToViewNameTranslator:当ModelAndView对象不为空且里面的属性为空才会生效,默认返回请求路径的viewName
- ViewResolver:视图解析器,将viewName解析为真正的view视图
- LocaleResolver:解析出用户的区域
- theseResolver:主题,一个主题对应一个properties文件,里面包含图片、颜色、css样式等;
- multipartResolver:将文件包装恒Multipart
- flashMapManager:用于重定向 Redirect 时的参数数据传递
源码解析
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);
//获取到handler (获取到controller的方法 handlerMethod)
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
//根据handler获取指定的HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
//是否直接用客户端的缓存
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;
}
// Actually invoke the handler.
//调用handler方法 (controller的方法) 如果是前后端分离 则此处会返回null
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
//当ModelAndView对象存在但对象内的view属性不存在则默认返回请求路径的viewName
applyDefaultViewName(processedRequest, mv);
//业务处理后调用拦截器的postHandle方法
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);
}
//将model数据填充到view里面,并执行拦截器的afterCompletion方法
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);
}
}
}
}
正文到此结束
热门推荐
该篇文章的评论功能已被站长关闭