SpringBoot注册Filter的几种方式

1.@WebFilter
通过 @WebFilter 注解来标记一个过滤器,这种方式相信大家很容易想到。这是将 Servlet 中的那一套东西直接拿到 Spring Boot 上用。

具体做法就是通过 @WebFilter 注解来标记一个 Filter,如下:

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("-----doFilter-----");
        chain.doFilter(request, response);
    }
}

在 @WebFilter 注解中可以配置过滤器的拦截规则。这个注解要生效,还需要我们在项目启动类上配置 @ServletComponentScan 注解,如下:

@SpringBootApplication
@ServletComponentScan
public class FilterdemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(FilterdemoApplication.class, args);
    }

}

@ServletComponentScan 注解虽然名字带了 Servlet,但是实际上它不仅仅可以扫描项目中的 Servlet 容器,也可以扫描 Filter 和 Listener。

这是我们在 Spring Boot 中使用过滤器的第一种方式,在实际项目中,这种方式使用较少,因为这种方式有一个很大的弊端就是无法指定 Filter 的优先级,如果存在多个 Filter 时,无法通过 @Order 指定优先级。

2.@Bean
第二种方式就是将过滤器配置成 Bean,注册到 Spring 容器中去。这种方法不再需要 @ServletComponentScan 注解,只要一个 Bean 即可,如下:

@Component
public class MyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("-----doFilter-----");
        chain.doFilter(request, response);
    }
}

这种方式看起来很方便,一个注解将 Filter 纳入到 Spring 容器中即可。而且这种方式还有一个优势,就是如果存在多个 Filter,可以通过 @Order 注解指定多个 Filter 的优先级,像下面这样:

@Component
@Order(-1)
public class MyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("-----doFilter-----");
        chain.doFilter(request, response);
    }
}

虽然解决了优先级问题,但是发现这种方式好像没有办法设置 Filter 的拦截规则!是的,直接定义 Bean 的话,默认的拦截规则就是 /* 即拦截所有请求,开发者无法进行自定义配置。

所以第三种方式就出来了
3.FilterRegistrationBean

第三种方案还是将 Filter 封装成一个 Bean,但这个 Bean 是 FilterRegistrationBean,通过 FilterRegistrationBean 我们既可以配置 Filter 的优先级,也可以配置 Filter 的拦截规则

一般在项目中,我们都是使用 FilterRegistrationBean 来配置过滤器,看一个案例:

@Configuration
public class FilterConfiguration {
    @Bean
    FilterRegistrationBean<MyFilter> myFilterFilterRegistrationBean() {
        FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new MyFilter());
        bean.setOrder(-1);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
    @Bean
    FilterRegistrationBean<MyFilter2> myFilterFilterRegistrationBean2() {
        FilterRegistrationBean<MyFilter2> bean = new FilterRegistrationBean<>();
        bean.setFilter(new MyFilter2());
        bean.setOrder(-2);
        bean.setUrlPatterns(Arrays.asList("/hello"));
        return bean;
    }
}

下面我们来看下FilterRegistrationBean的源码
Spring Boot 为了方便大家向 Servlet 容器中注册 Servlet、Filter 以及 Listener,提供了一个 Bean 注册的抽象类 RegistrationBean,如下:

public abstract class RegistrationBean implements ServletContextInitializer, Ordered {
 private int order = Ordered.LOWEST_PRECEDENCE;
 private boolean enabled = true;
 @Override
 public final void onStartup(ServletContext servletContext) throws ServletException {
  String description = getDescription();
  if (!isEnabled()) {
   logger.info(StringUtils.capitalize(description) + " was not registered (disabled)");
   return;
  }
  register(description, servletContext);
 }
 protected abstract String getDescription();
 protected abstract void register(String description, ServletContext servletContext);
 public void setEnabled(boolean enabled) {
  this.enabled = enabled;
 }
 public boolean isEnabled() {
  return this.enabled;
 }
 public void setOrder(int order) {
  this.order = order;
 }
 @Override
 public int getOrder() {
  return this.order;
 }

}

1.RegistrationBean 实现了 ServletContextInitializer 接口,在 Servlet 启动时,RegistrationBean#onStartup 方法会被调用,进而完成 Filter、Servlet 以及 Listener 的注册。

2.enabled 属性可以理解为一个开关,设置为 false 相当于关闭组件注册

RegistrationBean 有众多的实现类,我们之前使用的 FilterRegistrationBean 只是其中之一:
在这里插入图片描述
1.ServletListenerRegistrationBean 用来注册监听器。
2.ServletRegistrationBean 用来注册 Servlet。
3.DispatcherServletRegistrationBean 用来注册 DispatcherServlet。
4.FilterRegistrationBean 用来注册过滤器。
5.DelegatingFilterProxyRegistrationBean 则用来注册 DelegatingFilterProxy,DelegatingFilterProxy 在 Spring Security、Spring Session、Shiro 等整合时非常有用

==============================================
转载自:https://blog.csdn.net/qq_34136709/article/details/106849386

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot 中有几种方法可以添加 Filter: 1. 使用 @WebFilter 注解 使用 @WebFilter 注解将 Filter 标记为 Servlet 规范中的过滤器,然后将其注册到 Servlet 容器中: ``` @WebFilter(urlPatterns = "/*", filterName = "myFilter") public class MyFilter implements Filter { // ... } ``` 2. 使用 FilterRegistrationBean 使用 FilterRegistrationBean 可以将 Filter 注册到 Servlet 容器中: ``` @Bean public FilterRegistrationBean<MyFilter> filterRegistrationBean() { FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new MyFilter()); registrationBean.addUrlPatterns("/*"); registrationBean.setName("myFilter"); return registrationBean; } ``` 3. 在 web.xml 中配置 在 Spring Boot 项目中,可以在 `src/main/webapp/WEB-INF` 目录下的 `web.xml` 文件中配置 Filter。 例如: ``` <filter> <filter-name>myFilter</filter-name> <filter-class>com.example.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>myFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` 4. 使用 ServletContextInitializer 可以使用 ServletContextInitializer 接口的实现类来注册 Filter。 例如: ``` @Component public class MyFilterConfig implements ServletContextInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { FilterRegistration.Dynamic filter = servletContext.addFilter("myFilter", MyFilter.class); filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); } } ``` 希望这些信息能帮到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值