顾乔芝士网

持续更新的前后端开发技术栈

SpringBoot三剑客:拦截器、过滤器、AOP的实战

在SpringBoot项目中,拦截器(Interceptor)、过滤器(Filter)和AOP(Aspect Oriented Programming)经常让开发者产生选择困难。本文将结合实战场景和代码示例,解析三者的核心差异及最佳使用姿势。


一、概念速览

1. 过滤器(Filter)

Servlet规范定义,基于函数回调实现,作用于Web容器层面。所有请求进入DispatcherServlet前必经之路。

典型场景

  • 全局字符编码设置
  • XSS攻击防御
  • 敏感词过滤
  • 请求耗时统计
@Component
public class CharsetFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }
}

2. 拦截器(Interceptor)

Spring MVC机制,基于反射实现,可获取Spring上下文中的Bean。

典型场景

  • 接口权限验证
  • 用户登录状态检查
  • API请求日志记录
public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                            Object handler) {
        String token = request.getHeader("Authorization");
        return checkToken(token); // 返回false终止请求
    }
}

// 注册拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/api/**");
    }
}

3. AOP

面向切面编程,基于动态代理实现,可切入任意Spring管理的Bean。

典型场景

  • 服务层方法执行日志
  • 数据库事务管理
  • 接口性能监控
  • 业务操作审计
@Aspect
@Component
public class LogAspect {
    @Around("execution(* com.example.service.*.*(..))")
    public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long duration = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " 执行耗时: " + duration + "ms");
        return result;
    }
}

二、核心差异对比

维度

过滤器(Filter)

拦截器(Interceptor)

AOP

作用层级

Servlet容器

Spring MVC

Spring Bean

依赖框架

Servlet规范

Spring MVC

Spring AOP

获取上下文

无法获取Spring Bean

可以获取Spring上下文

直接操作Bean对象

执行顺序

最先执行

在DispatcherServlet之后

方法调用前后

处理粒度

请求级别

请求级别

方法级别

性能影响

动态代理带来轻微性能损耗


三、实战选择指南

1.必须使用过滤器的场景

  • 需要处理所有请求(包括静态资源)
  • 需要修改请求/响应内容(如压缩响应)
  • 需要处理非Spring管理的资源

2.优先选择拦截器的场景

  • 需要访问HandlerMethod等Spring MVC对象
  • 需要细粒度控制请求路径(通过PathPattern)
  • 需要处理与HTTP协议强相关的逻辑

3.AOP更适合的场景

  • 需要处理业务无关的横切关注点
  • 需要切入Service/Dao层方法
  • 需要灵活控制切入点(注解/包路径等)

四、组合使用案例:API安全防护

// 1. Filter处理XSS攻击
public class XssFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                        FilterChain chain) {
        chain.doFilter(new XssRequestWrapper((HttpServletRequest) request), response);
    }
}

// 2. Interceptor验证JWT
public class JwtInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, 
                             HttpServletResponse response, Object handler) {
        return validateJWT(request.getHeader("Authorization"));
    }
}

// 3. AOP记录敏感操作
@Aspect
@Component
public class AuditAspect {
    @AfterReturning(pointcut = "@annotation(auditLog)", returning = "result")
    public void auditLog(AuditLog auditLog, Object result) {
        // 记录操作日志到数据库
    }
}

五、避坑指南

  1. 执行顺序问题
  2. 过滤器链顺序:通过@Order控制
  3. 拦截器顺序:通过registry.addInterceptor()顺序控制
  4. AOP顺序:通过@Order注解指定
  5. 性能陷阱
  6. 避免在过滤器中处理复杂业务
  7. 拦截器preHandle中不要阻塞IO
  8. AOP切入点表达式不要过于宽泛
  9. 上下文限制
  10. 过滤器中无法使用@Autowired
  11. AOP无法拦截private方法
  12. 静态方法无法被AOP切入

结语

三者的选择没有绝对标准,关键要抓住本质差异:

  • 过滤器是Web容器的守门人
  • 拦截器是Spring MVC的安检员
  • AOP是业务逻辑的监视器

在实际项目中,通常三者会配合使用:过滤器处理底层协议问题,拦截器处理Web层逻辑,AOP处理业务层横切关注点。掌握它们的差异,才能写出更优雅、更高效的代码。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言