0
点赞
收藏
分享

微信扫一扫

Spring MVC多个拦截器执行顺序

何以至千里 2022-03-11 阅读 63

为了对比多个拦截器的执行顺序,先创建两个拦截器打比方

第一个拦截器:

public class MyInterceptor implements HandlerInterceptor {
    /**
     * 目标方法执行之前执行
     *
     * @return true不拦截,如果为false,那么后面一连串方法都不会执行(Controller。postHandle。afterCompletion。。等等)
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("preHandle1.....");
            return true;
    }

    /**
     * 在目标执行之后 视图返回之前执行
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle1.....");
    }

    /**
     * 在整个流程都执行完毕后执行,记录日志、异常等(用的不多)
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion1.....");
    }
}

第二个拦截器:

public class MyInterceptor2 implements HandlerInterceptor {
    /**
     * 目标方法执行之前执行
     *
     * @return true不拦截,如果为false,那么后面一连串方法都不会执行(Controller。postHandle。afterCompletion。。等等)
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle2.....");
        return true;
    }

    /**
     * 在目标执行之后 视图返回之前执行
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle2.....");
    }

    /**
     * 在整个流程都执行完毕后执行,记录日志、异常等(用的不多)
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion2.....");
    }
}

Spring MVC配置文件中配置拦截器:先配置拦截器1,再配置拦截器2

<!--    配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--            拦截路径,对哪些资源执行拦截操作  /**代表对所有都拦截-->
            <mvc:mapping path="/**"/>
            <bean class="com.interceptor.MyInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <!--            拦截路径,对哪些资源执行拦截操作  /**代表对所有都拦截-->
            <mvc:mapping path="/**"/>
            <bean class="com.interceptor.MyInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!--配置拦截器-->

启动Tomcat服务并访问相应资源,运行结果:

 调换SpringMVC配置文件拦截器的顺序:先配置拦截器2,再配置拦截器1

<!--    配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--            拦截路径,对哪些资源执行拦截操作  /**代表对所有都拦截-->
            <mvc:mapping path="/**"/>
            <bean class="com.interceptor.MyInterceptor2"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <!--            拦截路径,对哪些资源执行拦截操作  /**代表对所有都拦截-->
            <mvc:mapping path="/**"/>
            <bean class="com.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!--配置拦截器-->

再次运行Tomcat服务执行结果:

preHandle2.....
preHandle1.....
postHandle1.....
postHandle2.....
afterCompletion1.....
afterCompletion2.....

多个拦截器执行preHandle的顺序与Spring MVC配置文件中的配置顺序有关,将配置文件还原到拦截器1~拦截器2

<!--    配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--            拦截路径,对哪些资源执行拦截操作  /**代表对所有都拦截-->
            <mvc:mapping path="/**"/>
            <bean class="com.interceptor.MyInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <!--            拦截路径,对哪些资源执行拦截操作  /**代表对所有都拦截-->
            <mvc:mapping path="/**"/>
            <bean class="com.interceptor.MyInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!--配置拦截器-->

当第一个拦截器的preHandle方法返回true时,才会继续向下调用下一个拦截器的preHandle

修改一下代码,将第一个拦截器的preHandle方法改成false,试着运行程序,看看拦截器2的preHandle是否执行:

public class MyInterceptor implements HandlerInterceptor {
    /**
     * 目标方法执行之前执行
     *
     * @return true不拦截,如果为false,那么后面一连串方法都不会执行(Controller。postHandle。afterCompletion。。等等)
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("preHandle1.....");
            return false;
    }

    /**
     * 在目标执行之后 视图返回之前执行
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle1.....");
    }

    /**
     * 在整个流程都执行完毕后执行,记录日志、异常等(用的不多)
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion1.....");
    }
}

执行结果:

只有preHandle1被执行 ,说明拦截器1的preHandle返回false拦截器2压根就不会执行,甚至拦截器1的postHandle和afterCompletion也不会执行

举报

相关推荐

0 条评论