本文目录导读:

- 场景一:Web请求拦截(Filter vs Interceptor)
- 场景二:AOP 面向切面拦截(@Around)
- 场景三:MyBatis 拦截器(数据持久层)
- 场景四:消息队列拦截(MQ)
- 最终总结:到底选哪个?
你提到的“Java案例”比较宽泛,在Java开发中,“拦截数据”通常指的是在处理请求或数据流时,对数据进行拦截、过滤、监控、篡改或审计。
我不知道你具体指的是哪一种场景(是AOP拦截、Filter拦截、还是消息队列拦截?),为了给你最准确的答案,我把Java中最常见的四种“拦截数据”的机制进行对比,你可以根据你的场景对号入座:
Web请求拦截(Filter vs Interceptor)
如果你是在做Spring Boot/Spring MVC项目,拦截HTTP请求数据,通常有Filter和HandlerInterceptor两种选择。
| 对比维度 | Filter(过滤器) | HandlerInterceptor(拦截器) |
|---|---|---|
| 底层机制 | 基于 Servlet 规范,不依赖 Spring MVC。 | 基于 Spring MVC 框架,依赖 Spring 容器。 |
| 作用范围 | 最广,能拦截所有请求(包括静态资源、js/css、未走Controller的请求)。 | 较窄,只能拦截进入到 Controller 的请求(Handler)。 |
| 数据拦截能力 | 最强,可以修改 HttpServletRequest / HttpServletResponse 中的字节流数据(如将请求体加密/解密)。 |
中等,主要能获取请求头、参数,但很难修改请求体(request body)。 |
| 执行顺序 | 最先执行(在 Spring 容器之前)。 | 稍后执行(在 Spring 容器和 HandlerMapping 之后)。 |
| 适用场景 | 数据加解密、防XSS攻击、打印原始请求日志、跨域处理(CORS)。 | 登录权限校验、接口限流、权限动态判断、请求耗时统计。 |
👉 如果按“能拦多少”来算):Filter更好。 👉 如果按“操作灵活、与业务结合”来算):Interceptor更好。 如果你的需求是拦截数据流进行加解密或篡改,必须用 Filter(因为 Interceptor 拿到的是封装好的参数,无法改原始字节)。
AOP 面向切面拦截(@Around)
如果你打算用 Spring AOP 拦截某些Service或Mapper方法的数据(比如将方法的入参和返回值记录下来,或者对敏感字段脱敏)。
- 特点:极其灵活,可以根据方法名、注解自由指定拦截范围;既能拿到参数,也能拿到返回值。
- 缺点:性能开销相对较大(基于动态代理),且无法拦截静态方法、私有方法、final 类。
- 适用场景:业务日志记录、方法级权限校验、数据脱敏(对返回值里的手机号打码)、分布式锁。
👉 如果拦截的是“业务方法”里的数据,AOP(@Around)是唯一且最优的选择,没有之一。
MyBatis 拦截器(数据持久层)
如果你的需求是拦截 SQL 执行前后的数据(比如统一给 SQL 拼接租户ID、自动填充创建时间、分页插件)。
- 特点:基于 MyBatis 的
Interceptor,可以拦截Executor、StatementHandler等,能直接改写 SQL 语句。 - 适用场景:多租户数据隔离、慢SQL监控、自定义分页(如PageHelper原理)、数据审计。
👉 如果是拦截“数据库读写”的数据,必须用 MyBatis 拦截器;Filter 和 AOP 都做不了这一点。
消息队列拦截(MQ)
如果你是在用 Kafka / RocketMQ 消费数据,想拦截消息进行清洗和过滤。
- 特点:通常使用消息监听器(Listener) 加 自定义 Filter(如 Spring Cloud Stream)来拦截。
- 对比:Spring Cloud Stream 的
@StreamListener自带condition属性,比手动写 if 判断效率高;但若要对消息进行复杂的正则匹配或去重,Redis 布隆过滤器配合监听器更好。
👉 如果需求是“按内容过滤消息”,直接用 Listener 里的 condition 表达式;如果需求是“去重”,Redis + 布隆过滤器更好。
最终总结:到底选哪个?
| 你的核心需求 | 最佳选择 |
|---|---|
| 想拦截 HTTP 原始请求/响应字节流(加密、防XSS、CORS) | Filter(最底层,最靠谱) |
| 想拦截 Controller 层做权限校验、打访问日志 | HandlerInterceptor(更干净) |
| 想拦截 Service 层的业务数据(脱敏、审计) | AOP @Around(最灵活) |
| 想拦截 SQL 层的数据(分页、多租户、SQL监控) | MyBatis Interceptor(最专业) |
| 想拦截流式数据(处理消息队列) | 消息监听器 + Redis 去重(最高效) |
如果你能补充一下你遇到的具体案例背景(要拦截什么数据?在哪一层?是加密还是要日志?”),我可以直接告诉你那个案例里谁更好。