找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4425

积分

0

好友

579

主题
发表于 昨天 23:20 | 查看: 8| 回复: 0

这三者都是用来实现横切关注点(Cross-Cutting Concerns,如日志、权限、事务等)的技术,但作用层次、实现机制和适用范围差异很大。

核心区别对比

维度 Filter(过滤器) Interceptor(拦截器,Spring MVC) AOP(Aspect-Oriented Programming)
所属规范/框架 Servlet规范(javax.servlet.Filter) Spring MVC(HandlerInterceptor) Spring AOP 或 AspectJ
作用层次 Web容器(Servlet容器)级别 Spring MVC框架级别 Spring Bean方法级别(任意方法)
拦截范围 所有HTTP请求(包括静态资源、JSP、Servlet等) 只拦截DispatcherServlet处理的Handler(Controller方法) 可拦截Spring容器中任意Bean的任意方法
执行时机 请求进入容器后,Servlet之前;响应返回前 preHandle → Controller → postHandle → afterCompletion @Before、@After、@Around、@AfterReturning、@AfterThrowing
是否能注入Spring Bean 默认不能(需特殊处理) 可以 可以(天然支持)
是否能中断请求 可以(不调用chain.doFilter()) 可以(preHandle返回false) Around通知可控制是否执行目标方法
修改请求/响应 强(可包装HttpServletRequest/Response) 较弱(主要操作ModelAndView) 较弱(需通过ProceedingJoinPoint)
配置方式 web.xml 或 @WebFilter Spring配置类实现HandlerInterceptor + addInterceptors @Aspect + @Pointcut 或 XML
性能开销 最低 中等 较高(代理机制)
粒度 最粗(URL级别) 中等(Controller方法级别) 最细(方法、参数、异常等)

详细说明

Filter(过滤器)

  • 本质:Servlet规范的一部分,由Web容器(Tomcat等)直接管理。
  • 典型实现
    @WebFilter(urlPatterns = "/*")
    public class EncodingFilter implements Filter {
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
          // 处理请求
          chain.doFilter(req, res);  // 必须调用,否则请求中断
          // 处理响应
      }
    }
  • 适用业务场景
    • 全局性Web基础设施:字符编码转换、CORS跨域、请求/响应压缩(Gzip)、XSS/SQL注入过滤、静态资源访问控制、日志记录所有请求。
    • 不需要Spring参与的场景(如传统Servlet项目)。
    • 必须在Spring MVC之前的操作(如RequestWrapper包装)。

Interceptor(拦截器)

  • 本质:Spring MVC的组件,依赖于DispatcherServlet。
  • 典型实现
    @Component
    public class LoginInterceptor implements HandlerInterceptor {
      public boolean preHandle(HttpServletRequest request, ...) {
          // 登录校验、权限校验
          return true; // false则中断
      }
    }
  • 适用业务场景
    • Controller层面的统一处理:登录态校验、权限校验(RBAC)、接口限流、防重复提交、统一日志记录(含用户信息)、性能监控(方法耗时)。
    • 需要访问Spring上下文,但又不想侵入Controller代码的场景。
    • 比Filter更适合业务逻辑,因为能拿到HandlerMethod等Spring对象。

AOP(面向切面编程)

  • 本质:一种编程范式,通过动态代理(Spring AOP默认JDK/CGLIB)或静态织入(AspectJ)实现。
  • 典型实现
    @Aspect
    @Component
    public class LogAspect {
      @Around("execution(* com.example.service.*.*(..))")
      public Object around(ProceedingJoinPoint pjp) throws Throwable {
          // 前置
          Object result = pjp.proceed();  // 执行目标方法
          // 后置
          return result;
      }
    }
  • 适用业务场景(最强大、最灵活):
    • 服务层(Service)通用逻辑:事务管理(@Transactional 本质就是AOP)、缓存(@Cacheable)、异步(@Async)、统一异常处理、接口幂等性、分布式锁、审计日志(记录谁在什么时间改了什么)。
    • 非Web场景:定时任务、消息消费者、领域模型校验等。
    • 细粒度控制:只针对特定注解(如@Log)、特定包、特定参数等。
    • 复杂业务规则:如“所有涉及金额的操作都要审计”。

选择建议(优先级顺序)

  1. 优先考虑AOP(推荐)
    现代Spring Boot项目中,AOP是最常用、最优雅的方式。能解决大部分横切问题,且可复用性最高。
  2. 需要Web容器级别的处理 → 用 Filter
    (编码、CORS、安全过滤等必须早于Spring MVC的)
  3. Controller层特定处理 → 用 Interceptor
    (登录、权限等和MVC紧密相关的)

组合使用很常见:

  • Filter → Interceptor → AOP(执行顺序从外到内)

实际项目中的典型分层

  • 安全/编码/CORS → Filter
  • 登录/权限/限流 → Interceptor 或 AOP(推荐用注解 + AOP更灵活)
  • 事务/缓存/日志/监控 → AOP
  • 全局异常@ControllerAdvice(本质也是AOP思想)



上一篇:数据库50年换岗:Agent时代PostgreSQL如何重构AI原生底座
下一篇:OpenAI低调发布GPT-Live:纯语音多Agent协同,打工人的《Her》时代已至
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-7-26 08:04 , Processed in 0.993689 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表