Spring的执行顺序:DispatcherServlet中央调度器

  • Post author:
  • Post category:其他




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--

,所以表面上就成了入栈出栈的执行顺序


加粗样式



版权声明:本文为m0_56079407原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。