自定义Filter,首先要本身写一个类,实现java.sevlet.Filter接口的init、doFilter和destroy三个方法。java
在web项目中,经过web.xml中的<filter>标签,能够将该自定义filter交由容器实例化,而后经过<filter-mapping>标签配置过滤路径。若是须要将该filter使用spring管理,好比该filter须要用到spring的其余bean,那么能够在web.xml中配置spring的filter代理类org.springframework.web.filter.DelegatingFilterProxy实现,在spring中实例化须要代理的filer为bean,只要保证<filter-name>和bean的id一致便可。注意须要设置代理filter的targetFilterLifecycle为true: web
<filter> <filter-name>myfilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <!-- 这个配置我没听懂说的什么意思,大概是说保证bean的生命周期要和filter保持一致 --> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>myfilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
在springboot中项目中有三种方式让该自定义filter生效。spring
1.方法一: springboot提供了注册filer的类FilterRegistrationBean,实例化该类可注册自定义filter,代码以下:springboot
@Configuration public class ApplicationConfiguration{ @Bean public FilterRegistrationBean myFilter() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); MyFilter myFilter = new MyFilter(); filterRegistrationBean.setFilter(myFilter); List<String> urls = new ArrayList<>(); urls.add("/users/*"); filterRegistrationBean.setUrlPatterns(urls);//配置过滤规则 return filterRegistrationBean; } }
Springboot还提供了注解实现的方式,这里再也不赘述,主要是自定义filter类上增长@WebFilter的注解来实现。app
2.方法二,借助spring的filter代理类DelegatingFilterProxy和springboot的FilterRegistrationBean一块儿实现,代码以下:url
@Configuration public class ApplicationConfiguration{ @Bean public FilterRegistrationBean myFilter() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new DelegatingFilterProxy("myFilter")); filterRegistration.addInitParameter("targetFilterLifecycle", "true"); filterRegistration.setEnabled(true); filterRegistration.addUrlPatterns("/*"); return filterRegistrationBean; } }
springboot中还有一种合并起来的写法,代码以下:代理
@Configuration public class ApplicationConfiguration{ @Bean public DelegatingFilterProxyRegistrationBean delegatingFilterProxyRegistrationBean(){ DelegatingFilterProxyRegistrationBean bean = new DelegatingFilterProxyRegistrationBean("myFilter"); bean.addInitParameter("targetFilterLifecycle", "true"); bean.setEnabled(true); bean.addUrlPatterns("/*"); return bean; } }
3.方法三,直接实例化自定义的Filter,可是这种Filter没法定义拦截规则,默认全局拦截,慎用。code
第一种和第二种方法本质是同样的,,主要就是FilterRegistrationBean这个类,经过AbstractFilterRegistrationBean接口间接实现了ServletContextInitializer,在springboot中启动容器后会查找实现该接口的bean,并调用onStartup()
方法将自定义的Filter添加到容器中。xml
二者的区别是方法一直接设置Filter,该Filter能够不用spring管理,好比上面方法一的代码所示,直接new MyFilter(),也能够由spring管理,好比将new MyFilter()的地方换成方法三的方式实现(此时方法三形式的filter将不会做为全局过滤器了)。而方法二经过DelegatingFilterProxy传入filter名字,在WebApplicationContext
查找该Filter Bean,并将DelegatingFilterProxy生成的Bean做为filter的代理对象,这样作的目的是,和有web.xml时的项目同样,容器加载时先加载代理Filter,不须要直接加载真正的Filter,达到懒加载的效果(有web.xml时的项目使用代理filter,必须懒加载,由于在web.xml加载filter的时候,spring中真正的filter bean尚未建立。)。对象