SpringBoot中的拦截器
Filter
典型场景 全局鉴权/接口耗时统计
@WebFilter("/*")
public class CostFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
long start = System.currentTimeMillis();
chain.doFilter(req, res); // 放行江湖令箭
System.out.println("接口耗时:"+(System.currentTimeMillis()-start)+"ms");
}
}
HandlerInterceptor
典型场景 接口权限验证/请求参数自动装填
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("X-Token");
if(!"vip666".equals(token)){
response.setStatus(403);
return false;
}
return true;
}
}
@Configuration
publicclass WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/login");
}
}
AOP拦截
典型场景 服务层方法缓存/事务管理
@Aspect
@Component
public class CacheAspect {
@Around("@annotation(com.example.anno.Cacheable)")
public Object aroundCache(ProceedingJoinPoint jp) {
String cacheKey = buildKey(jp);
Object cacheVal = redisTemplate.opsForValue().get(cacheKey);
if(cacheVal != null) return cacheVal;
Object result = jp.proceed();
redisTemplate.opsForValue().set(cacheKey, result, 5, TimeUnit.MINUTES);
return result;
}
}
RestTemplate
典型场景 统一添加请求头/加密请求参数
public class TraceInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) {
request.getHeaders().add("X-TraceId", UUID.randomUUID().toString());
return execution.execute(request, body);
}
}
// 注册水军
@Bean
public RestTemplate restTemplate() {
RestTemplate rt = new RestTemplate();
rt.getInterceptors().add(new TraceInterceptor());
return rt;
}
Feign拦截器
典型场景 统一签名计算/Header透传
public class FeignAuthInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
template.header("Authorization", "Bearer " + SecurityContext.getToken());
}
}
@Configuration
public class FeignConfig {
@Bean
public FeignAuthInterceptor feignAuthInterceptor() {
returnnew FeignAuthInterceptor();
}
}
WebFilter
典型场景 响应式编程统一编码/跨域处理
@Component
public class CorsWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("Access-Control-Allow-Origin", "*");
return chain.filter(exchange);
}
}
总结
顺序
Filter -> Interceptor -> AOP ,越早拦截越省力(但别在Filter里做业务)
性能
用Arthas监控拦截链路耗时
# 查看HandlerInterceptor耗时
trace *.preHandle '#cost>10'
# 诊断AOP切面
watch com.example.aop.*Aspect * '{params,returnObj}' -x 3