一直以来没有仔细研究过Filter和Intercepter,意识到过滤器的拦截器的认识很模糊。所以仔细学习了一下。其实还是很简单的。本来想把Filter和Interceptor写在一起,文章太长了还是分两篇写吧~
区别
过滤器和拦截器最大的区别在于:过滤器是servlet的规范规定的,只能用于过滤请求,而interceptor是Spring里面基于切面编程的一种实现。
过滤器作用于请求到达servlet之前,在spring中也就是在dispacherServlet之前。而拦截器最早只能作用于请求到达servlet之后。
基于这个特点,过滤器经常被用于处理请求的编码格式,session,日志等。
业务逻辑大多实现在拦截器中。
Filter
Spring的过滤器在Spring-web的包里。
现有的filter类结构图如下,这是直接从网上找的图,懒得自己再画了。
通常实现拦截器的方式:
- 实现
javax.servlet.Filter
接口,Filter
是servlet包的定义的接口,现有的这种实现方法有CompositeFilter
- 继承抽象类
GenericFilterBean
这个类实现了Filter接口。现有的实现有DelegatingFilterProxy
- 继承抽象类
OncePerRequestFilter
这个类是GenericFilterBean
的子类。现有的实现类有:CharacterEncodingFilter
、HiddenHttpMethodFilter
、HttpPutFormContentFilter
、RequestContextFilter
和ShallowEtagHeaderFilter
- 继承抽象类
AbstractRequestLoggingFilter
,该类为OncePerRequestFilter
的直接子类,这一类过滤器包括CommonsRequestLoggingFilter
、Log4jNestedDiagnosticContextFilter
和ServletContextRequestLoggingFilter
。
GenericFilterBean
从类结构图可以看到,这个类是Spring中直接实现了servlet的Filter的抽象类。所有的Filter都是基于这个类来实现的。
类的定义如下(Spring4.3):
public abstract class GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware, EnvironmentCapable, ServletContextAware, InitializingBean, DisposableBean {
...}
实现的接口有:
- Filter:过滤器的实现
- BeanNameAware:setBeanName方法,便于Bean管理器生成Bean
- EnvironmentAware:用于指明Bean的运行环境
- EnvironmentCapable:用于获取bean的运行环境
- ServletContextAware:实现该接口的setServletContextAware方法,指明ServletContext
- InitializingBean:实现该接口的afterPropertiesSet方法,在Bean初始化时设置属性
- DisposableBean :实现该接口的destroy方法,用于回收资源。