在Spring Boot中,你可以通过多次调用registry.addInterceptor()
来注册多个拦截器,并通过order()
方法或添加顺序来控制它们的执行顺序。以下是具体实现方式:
1. 注册多个拦截器并控制顺序
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private VideoInterceptor videoInterceptor;
@Autowired
private AnotherInterceptor anotherInterceptor;
@Autowired
private LoggingInterceptor loggingInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 第一个拦截器(最后执行)
registry.addInterceptor(loggingInterceptor)
.addPathPatterns("/**")
.order(3); // 数字越大,优先级越低
// 第二个拦截器
registry.addInterceptor(anotherInterceptor)
.addPathPatterns("/api/**")
.order(2);
// 第三个拦截器(最先执行)
registry.addInterceptor(videoInterceptor)
.addPathPatterns("/video/**")
.order(1); // 数字越小,优先级越高
}
}
2. 关于执行顺序的关键点
order值决定顺序:
order()
值越小,拦截器越先执行类似Filter的链式调用,但顺序与Filter相反
执行流程:
请求进入时:order小的先执行
响应返回时:order小的后执行
比如order(1)的拦截器:
preHandle
最先执行,postHandle
和afterCompletion
最后执行
如果不指定order:
默认按添加顺序执行(最后添加的优先级最低)
但显式指定order是更可靠的做法
3. 实际应用示例
假设你需要:
先验证权限(order=1)
然后记录日志(order=2)
最后处理视频请求(order=3)
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 1. 权限验证(最先执行)
registry.addInterceptor(authInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/public/**")
.order(1);
// 2. 日志记录
registry.addInterceptor(loggingInterceptor)
.addPathPatterns("/**")
.order(2);
// 3. 视频处理(最后执行)
registry.addInterceptor(videoRequestInterceptor)
.addPathPatterns("/hls/**")
.order(3);
}
4. 注意事项
如果多个拦截器拦截同一路径,order小的会先执行
某个拦截器的
preHandle
返回false时,后续拦截器和控制器都不会执行推荐为每个拦截器明确指定order,避免不可预期的行为
通过这种方式,你可以灵活控制多个拦截器的执行顺序和拦截范围。