前言
上一篇中,我们在过滤器、拦截器中,结合 Redis 加入幂等性校验功能;
在最后的时候,留下了一个问题,就是为什么这样做,而不用AOP ?
今天我们就来探讨下。
过滤器
过滤器可以拦截到方法的请求和响应(ServletRequest request, ServletResponse response),并对请求响应做出过滤操作;
过滤器依赖于servlet容器。在实现上,基于函数回调,它可以对几乎所有请求进行过滤,一个过滤器实例只能在容器初始化时调用一次;
使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,最后Filter再对服务器响应进行后处理;
过滤器的作用(摘自JavaDoc)
Examples that have been identified for this design are
- Authentication Filters, 即用户访问权限过滤
- Logging and Auditing Filters, 日志过滤,可以记录特殊用户的特殊请求的记录等
- Image conversion Filters
- Data compression Filters
- Encryption Filters
- Tokenizing Filters
- Filters that trigger resource access events
- XSL/T filters
- Mime-type chain Filter
拦截器
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作;
拦截器的作用
日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等
权限检查:如登录检测,进入处理器检测检测是否登录
性能监控:通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间。(反向代理,如apache也可以自动记录);
通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现
切面
相比过滤器,拦截器能够知道用户发出的请求最终被哪个控制器处理,但是拦截器还有一个明显的不足,即不能够获取request的参数以及控制器处理之后的response,所以就有了切片的用武之地了;
过滤器、拦截器以及切片的调用顺序
Filter->Intercepto->Aspect->Controller
过滤器和拦截器的区别
Filter | Interceptor | |
---|---|---|
实现方式 | 过滤器是基于函数回调 | 基于Java的反射机制的 |
规范 | Servlet规范 | Spring规范 |
作用范围 | 对几乎所有的请求起作用 | 只对action请求起作用 |