子容器创建完成后,当有请求到来时,DispatcherServlet就可以进行分发处理了。我们首先根据Servlet规范查找doService()
方法,这个方法在DispatcherServlet
本身就有实现:
@Override protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ... ...
try {
doDispatch(request, response);
} finally {
// ... ...
}
我们省去了无关代码,于是可以明显看出doDispatch()
才是分发请求的主要实现方法:
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
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// 查找能够处理当前请求的Handler
Adapter HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// ... ...
// 拦截器的preHandle()方法就是在这里被调用的
// 可见,如果preHandle()方法返回false,则终止分发流程,直接返回
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
} try {
// 这一行是对我们写的Controller方法的真正调用
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
}
applyDefaultViewName(request, mv);
// 拦截器的postHandle()方法就是在这里被调用的,即在Controller调用完成之后
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception ex) {
dispatchException = ex;
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
} catch (Exception ex) {
// ... ...
} finally {
// ... ...
}
}
分析到这里,DispatcherServlet的分发请求处理流程就一目了然了。
版权声明:本文为博主原创文章,转载请注明出处和原作者。https://blog.csdn.net/neosmith/article/details/44206671