Controller请求调用顺序
controller 中所有的请求都要经过
核心组件
DispatcherServlet
路由
,都会执行它的
doDispatch()
方法,
而拦截器postHandle()、preHandle()方法便是在其中调用的。
DispatcherServlet类:路由,中央调度器
-
HTTP请求处理程序/控制器的中央调度器
doDispatch中央调度方法
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
...........
try {
// 获取可以执行当前Handler的适配器
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 (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
// 注意: 执行Interceptor中PreHandle()方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 注意:执行Handle【包括我们的业务逻辑,当抛出异常时会被Try、catch到】
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
// 注意:执行Interceptor中PostHandle 方法【抛出异常时无法执行】
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
}
...........
}
为何拦截器的pre和post执行顺序是栈顺序
看看两个方法
applyPreHandle()
、
applyPostHandle()
具体是如何被调用的,就明白为什么postHandle()、preHandle() 执行顺序是相反的了。
正是因为
DispathcherServlet类中的doDispach()方法
进行调度的时候,
实际上
是调用了
applyPreHandler()和applyPostHandler()
,而这两个方法中的for循环遍历
interceptorList
数组时一个是
i++
一个是
i--
,所以表面上就成了入栈出栈的执行顺序
加粗样式