spring拦截器的实现方式和执行顺序。(用springboot快速搭建个web项目,用于测试)
    拦截器有两种方式,继承HandlerInterceptorAdapter 或者实现HandlerInterceptor 如下三个拦截器

    1. @Component
    2. public class FirstInterceptor extends HandlerInterceptorAdapter {
    3. @Override
    4. public boolean preHandle(HttpServletRequest request,
    5. HttpServletResponse response, Object handler) throws Exception {
    6. System.out.println("FirstInterceptor: preHandle");
    7. return true;
    8. }
    9. @Override
    10. public void postHandle(HttpServletRequest request, HttpServletResponse response,
    11. Object handler, ModelAndView modelAndView) throws Exception {
    12. System.out.println("FirstInterceptor: postHandle");
    13. }
    14. @Override
    15. public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
    16. Object handler, Exception ex) throws Exception {
    17. System.out.println("FirstInterceptor: afterCompletion");
    18. }
    19. }
    1. @Component
    2. public class SecondInterceptor extends HandlerInterceptorAdapter {
    3. @Override
    4. public boolean preHandle(HttpServletRequest request,
    5. HttpServletResponse response, Object handler) throws Exception {
    6. System.out.println("SecondInterceptor: preHandle");
    7. return true;
    8. }
    9. @Override
    10. public void postHandle(HttpServletRequest request, HttpServletResponse response
    11. , Object handler, ModelAndView modelAndView) throws Exception {
    12. System.out.println("SecondInterceptor: postHandle");
    13. }
    14. @Override
    15. public void afterCompletion(HttpServletRequest request, HttpServletResponse response
    16. , Object handler, Exception ex) throws Exception {
    17. System.out.println("SecondInterceptor: afterCompletion");
    18. }
    19. }
    1. @Component
    2. public class ThirdInterceptor implements HandlerInterceptor {
    3. @Override
    4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response
    5. , Object handler) throws Exception {
    6. System.out.println("ThirdInterceptor: preHandle");
    7. return true;
    8. }
    9. @Override
    10. public void postHandle(HttpServletRequest request, HttpServletResponse response
    11. , Object handler, ModelAndView modelAndView) throws Exception {
    12. System.out.println("ThirdInterceptor: postHandle");
    13. }
    14. @Override
    15. public void afterCompletion(HttpServletRequest request, HttpServletResponse response
    16. , Object handler, Exception ex) throws Exception {
    17. System.out.println("ThirdInterceptor: afterCompletion");
    18. }
    19. }

    注册拦截器

    1. @Configuration
    2. public class WebMvcConfig implements WebMvcConfigurer {
    3. @Override
    4. public void addInterceptors(InterceptorRegistry registry) {
    5. //FirstInterceptor 拦截除了/test2/** 以外的所有请求
    6. InterceptorRegistration first = registry.addInterceptor(new FirstInterceptor());
    7. first.addPathPatterns("/**");
    8. first.excludePathPatterns("/test2/**");
    9. //SecondInterceptor 拦截所有的请求
    10. InterceptorRegistration second = registry.addInterceptor(new SecondInterceptor());
    11. second.addPathPatterns("/**");
    12. //ThirdInterceptor 拦截所有的请求
    13. InterceptorRegistration third = registry.addInterceptor(new ThirdInterceptor());
    14. third.addPathPatterns("/**");
    15. }
    16. }

    新建个请求,测试拦截器

    1. @RestController
    2. public class IndexController {
    3. @RequestMapping("/test1/index")
    4. public String index1() {
    5. System.out.println("IndexController test1/index");
    6. return "test1 index";
    7. }
    8. @RequestMapping("/test2/index")
    9. public String index2() {
    10. System.out.println("IndexController test2/index");
    11. return "test2 index";
    12. }
    13. }

    正常情况下执行test1/index,查看拦截器执行情况

    1. FirstInterceptor: preHandle
    2. SecondInterceptor: preHandle
    3. ThirdInterceptor: preHandle
    4. IndexController test1/index
    5. ThirdInterceptor: postHandle
    6. SecondInterceptor: postHandle
    7. FirstInterceptor: postHandle
    8. ThirdInterceptor: afterCompletion
    9. SecondInterceptor: afterCompletion
    10. FirstInterceptor: afterCompletion

    结论:
    执行顺序按照注册的顺序来执行,如果我们有N个拦截器,那么执行顺序如下:
    首先顺序执行N个拦截器的preHandle()方法

    1:preHandle()—>2:preHandle()…—>n:preHandle()

    然后执行我们的controller

    test1/index

    紧接着倒序执行postHandle()方法

    n:postHandle()—>n-1:postHandle()…—>1:postHandle()

    最后倒序执行afterCompletion()方法

    n:afterCompletion()—>n-1:afterCompletion()…—>1:afterCompletion()

    如果其中一个拦截器返回false,例如我们让ThirdInterceptor返回false,那么执行情况是

    1. FirstInterceptor: preHandle
    2. SecondInterceptor: preHandle
    3. ThirdInterceptor: preHandle
    4. SecondInterceptor: afterCompletion
    5. FirstInterceptor: afterCompletion

    结论:
    执行顺序按照注册的顺序来执行,如果我们有N个拦截器,第m个拦截器拦截后返回false,那么执行顺序如下:
    首先顺序执行到第m个拦截器的preHandle()方法

    1:preHandle()—>2:preHandle()…—>m:preHandle()

    此时第m个拦截器成功拦截了请求,返回false,此时便会倒序执行前面的afterCompletion()方法

    m-1:afterCompletion()—>m-2:afterCompletion()…—>1:afterCompletion()