Spring中的过滤器
一. 配置方法及其特点
1. 方法一
1)步骤:
①. 新建类实现实现Filter接口,实现接口的抽象方法:init、doFilter、destroy(init,destroy有默认实现,一般实现doFilter方法就好
②. 为新建类添加注解@WebFilter(urlPatterns = “/*”, filterName = “logFilter”)
@WebFilter(urlPatterns = "/*", filterName = "webSecurityFilter")
public class WebSecurityFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
//TODO
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
③. 在启动类上添加过滤器包扫描注解@ServletComponentScan(“com.xlt.filter”),或者直接在步骤②中为每个过滤器添加@Component注解,两者效果是一样的
@SpringBootApplication(scanBasePackages = "com.xlt")
@ServletComponentScan("com.xlt.filter")
public class DemoWebApplication {
public static void main(String[] args) {
SpringApplication.run(DemoWebApplication.class, args);
}
}
2)特点:
①. 这种配置方法无法显式指定过滤器的执行顺序,不过我们能通过编辑过滤器类名来决定其执行顺序(先后顺序为数字由小到大,字母由A-Z)
附:StackOverFlow连接
3)备注:
①. 若在步骤③中,两个注解同时添加,且@WebFilter注解的filterName属性恰好是首字母小写的类名时,则会有导致Bean重名的情况,这样做也没有什么意义,只不过是把一个过滤器分别以两个不同的名字,添加了两遍到过滤器链中
2. 方法二
1)步骤:
①. 使用配置类,添加@Configuration注解
②. 添加过滤器注册bean
③. 注册过滤器并配置属性
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegistration2() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new WebSecurityFilter());
registration.addUrlPatterns("/*");
registration.setName("webSecurityFilter");
registration.setOrder(1);
return registration;
}
}
2)特点:
①. 该配置方式中我们可以通过过滤器注册Bean的setOrder方法显示指定过滤起的执行顺序(数字小的先执行)
②. 项目中其他地方并不会用到过滤器实例,所有在该种配置方式中,我们可以用内部类的方式来定义过滤器
附:Java内部类
③. 该配置方式中我们手动实例化过滤器,并指定其各属性,所以过滤器类就不要任何注解来修饰
3. 方法三
1)步骤:
①.通过xml文件配置(不过spring boot一般没有web.xml)
<filter>
<filter-name>FilterTest</filter-name>
<filter-class>com.xlt.filter.WebSecurityFilter</filter-class>
</filter>
<!--映射过滤器-->
<filter-mapping>
<filter-name>webSecurityFilter</filter-name>
<!--“/*”表示拦截所有的请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
2)特点:
①. 该种配置方式过滤器的执行先后顺序由在web.xml中由上到下的位置决定
二. 过滤器链
1. 每个过滤器doFilter方法的参数列表都有一个FilterChain参数,其表示Spring容器中所有过滤器的一个变长列表,每次在过滤器中调用FilterChain.doFilter()方法,都会调用变长列表中的下一个过滤器的doFilter方法
2. 执行顺序
过滤器doFilter方法中,参数FilterChain调用doFilter方法表示调用过滤器链中下一个过滤器,所以每个过滤器doFilter方法中的代码都分为两部分,过滤前,和过滤后,以FilterChain调用doFiter为界限,过滤器链中这两部分的执行顺序为,以过滤器链中先入顺序为主:过滤器一过滤前,过滤器二过滤前,调用controller层,过滤器二过滤后,过滤器一过滤后
三. 总结
1.过滤器与拦截器的区别
①. Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用
②. Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理的方式来执行。
③. Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。