spring-mvc执行流程
注:Handler并不是具体的类或接口(实际上是
Object
),而是一个概念。Controller
是Handler的一种情况
Spring MVC采用了前端控制器模式(the front controller pattern),处于核心位置的DispatcherServlet
调度其它组件完成对客户端的请求与响应。
1.用户请求发送到服务器,服务器,例如Tomcat创建并初始化httpServletRequest
和httpServletResponse
对象,交给DispatcherServlet
进行管理
2.DispatcherServlet
将请求委托给HandlerMapping
进行处理,后者处理完毕后,会返回一个HandlerExecutionChain
对象
@Nullable
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处理器(例如,Controller
)对象和多个Handler拦截器(HandlerInterceptor
)对象
3.DispatcherServlet
从所有的Handler适配器中找到可以处理当前Handler的适配器(适配器模式)
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
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");
}
4.获取到Handler适配器后,DispatcherServlet
委托Handler适配器,执行Handler中的代码,返回ModelAndView
对象
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
//...
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//...
}
5.得到了ModelAndView
对象后,就可以开始渲染了
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
//...
if (mv != null && !mv.wasCleared()) {
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
//...
}
首先,从ModelAndView
对象中得到逻辑视图名
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
//...
View view;
String viewName = mv.getViewName();
if (viewName != null) {
// We need to resolve the view name.
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
if (view == null) {
throw new ServletException("Could not resolve view with name '" + mv.getViewName() +
"' in servlet with name '" + getServletName() + "'");
}
}
//...
}
然后,根据视图名,依次尝试可用的ViewResolver
进行视图解析,如果成功,就返回View
对象
@Nullable
protected View resolveViewName(String viewName, @Nullable Map<String, Object> model,
Locale locale, HttpServletRequest request) throws Exception {
if (this.viewResolvers != null) {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
}
return null;
}
6.获取到View
对象后,调用由模板引擎实现的的render()
方法,将模型数据渲染到模板中
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
//...
view.render(mv.getModelInternal(), request, response);
//...
}
7.返回控制权给DispatcherServlet
,由DispatcherServlet
将响应(通过服务器)返回给用户
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
//...
try {
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);
}
}
ServletRequestPathUtils.setParsedRequestPath(previousRequestPath, request);
}
}