SpringBoot中提供了HandlerInterceptorAdapter适配器供我们自定义拦截器,可以拦截自定义或所有的请求做相应的处理。
HandlerInterceptorAdapter中共有四个方法:
- preHandle :在Controller方法被调用前执行
- postHandle :在Controller方法调用后执行
- afterCompletion :在整个请求处理完成之后执行
- afterConcurrentHandlingStarted :用来处理异步请求,当Controller中有异步请求方法的时候会触发该方法。

实现步骤
自定义拦截器
继承HandlerInterceptorAdapter,重写方法(在实际项目中,可以按照实际的业务重写方法,不需要重写全部四个方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
@Component @Slf4j public class MyInterceptor1 extends HandlerInterceptorAdapter {
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("----- preHandle(1) -----"); return super.preHandle(request, response, handler); }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("----- postHandle(1) -----"); super.postHandle(request, response, handler, modelAndView); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("----- afterCompletion(1) -----"); super.afterCompletion(request, response, handler, ex); }
@Override public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("----- afterConcurrentHandlingStarted(1) -----"); super.afterConcurrentHandlingStarted(request, response, handler); } }
|
注册拦截器
实现WebMvcConfigurer,注册拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
@Configuration public class InterceptorConfig implements WebMvcConfigurer {
@Autowired private MyInterceptor1 myInterceptor1;
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor1); } }
|
上面实现的是自定义一个拦截器的情景,但是一般在实际项目中会需要自定义多个拦截器,那么这些拦截器的执行顺序又是如何确定的呢?拦截器内部的方法的执行顺序又是怎样的呢?
自定义多个拦截器
定义MyInterceptor2拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
@Component @Slf4j public class MyInterceptor2 extends HandlerInterceptorAdapter {
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("----- preHandle(2) -----"); return super.preHandle(request, response, handler); }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("----- postHandle(2) -----"); super.postHandle(request, response, handler, modelAndView); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("----- afterCompletion(2) -----"); super.afterCompletion(request, response, handler, ex); }
@Override public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("----- afterConcurrentHandlingStarted(2) -----"); super.afterConcurrentHandlingStarted(request, response, handler); } }
|
将自定义的MyInterceptor2拦截器注册到容器中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
@Configuration public class InterceptorConfig implements WebMvcConfigurer {
@Autowired private MyInterceptor1 myInterceptor1;
@Autowired private MyInterceptor2 myInterceptor2;
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor1); registry.addInterceptor(myInterceptor2); } }
|
此时我们定义了两个拦截器,且注册的时候,先注册MyInterceptor1拦截器,再注册MyInterceptor2拦截器,接下来测试一下他们的执行顺序。
使用postman模拟请求,打印日志


结论
由测试结果可以得出:
- 拦截器的执行顺序_按照注册顺序_。
- 方法的执行顺序按照:preHandle()方法按照正序执行,postHandle()、afterCompletion()方法按照倒序执行。
自定义拦截URL
在注册拦截器如果不指定拦截的URL则默认所有的URL都会被拦截。我们也可以在注册拦截器时自定义该拦截器需要拦截的URL。

使用postman模拟请求,查看日志:

