手把手教你SpringBoot过滤器N种注册方式

要说在 Spring Boot 中注册过滤器有三种方式,你都能想到哪些呢?今天松哥就来和大家聊一聊 Spring Boot 中注册过滤器的三种方式!

其实本来是想和大家聊 Spring Security 过滤器链的问题的,结果看源码看着看着就跑题了,索性就先和大家聊一聊 Spring Boot 中注册过滤器的三种方式,算是给 后面的 Spring Security 打一点基础。

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;
  }
}

4.扩展

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;
 }

}

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

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

RegistrationBean 有众多的实现类,我们之前使用的 FilterRegistrationBean 只是其中之一:

实现类的作用一目了然:

  • ervletListenerRegistrationBean 用来注册监听器。
  • ServletRegistrationBean 用来注册 Servlet。
  • DispatcherServletRegistrationBean 用来注册 DispatcherServlet。
  • FilterRegistrationBean 用来注册过滤器。
  • DelegatingFilterProxyRegistrationBean 则用来注册 DelegatingFilterProxy,DelegatingFilterProxy 在 Spring Security、Spring Session、Shiro 等整合时非常有用。

5.小结

今天就和小伙伴们分享一下 Spring Boot 中过滤器的三种注册方式,顺带和大家分享了一下 FilterRegistrationBean 的继承体系,小伙伴们可以根据 FilterRegistrationBean 的继承体系中的实现类,自行尝试一下 Servlet 和 Listener 的注册方式~本文案例下载地址:https://github.com/lenve/javaboy-code-samples

到此这篇关于手把手教你SpringBoot过滤器N种注册方式的文章就介绍到这了,更多相关SpringBoot过滤器注册内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot 增加过滤器方法操作示例

    本文实例讲述了springboot 增加过滤器方法操作.分享给大家供大家参考,具体如下: 在访问服务器时,我们需要控制用户是否允许权限,这个时候可以使用过滤器. 在springboot 配置过滤器的方法如下: 编写过滤器代码: package com.neo.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.

  • 简单了解SpringBoot过滤器及使用方式

    过滤器简介 过滤器依赖Servlet容器,属于Servlet规范的一部分. 在实现上基于Servlet容器的函数回调,可以对几乎所有请求进行过滤. Filter的生命周期由Servlet容器管理. 过滤器执行流程 过滤器配置使用方式一 @Order(1) // 指定过滤器的执行顺序 @WebFilter(filterName = "CostTimeFilter", urlPatterns = "/*" , initParams = { @WebInitParam(n

  • SpringBoot实现拦截器、过滤器、监听器过程解析

    这篇文章主要介绍了SpringBoot实现拦截器.过滤器.监听器过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 过滤器 过滤器简介 过滤器的英文名称为 Filter, 是 Servlet 技术中最实用的技术.如同它的名字一样,过滤器是处于客户端和服务器资源文件之间的一道过滤网,帮助我们过滤掉一些不符合要求的请求,通常用作 Session 校验,判断用户权限,如果不符合设定条件,则会被拦截到特殊的地址或者基于特殊的响应. 过滤器的使用 首

  • springboot @WebFilter注解过滤器的实现

    @WebFilter注解过滤器 @WebFilter加在过滤器的注解上使用 import lombok.extern.slf4j.Slf4j; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; impo

  • SpringBoot实现过滤器、拦截器与切片的实现和区别

    Q:使用过滤器.拦截器与切片实现每个请求耗时的统计,并比较三者的区别与联系 过滤器Filter 过滤器概念 Filter是J2E中来的,可以看做是 Servlet 的一种"加强版",它主要用于对用户请求进行预处理和后处理,拥有一个典型的 处理链 .Filter也可以对用户请求生成响应,这一点与Servlet相同,但实际上很少会使用Filter向用户请求生成响应.使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,最后Filt

  • 详谈springboot过滤器和拦截器的实现及区别

    前言 springmvc中有两种很普遍的AOP实现: 1.过滤器(Filter) 2.拦截器(Interceptor) 本篇面对的是一些刚接触springboot的人群 所以主要讲解filter和interceptor的简单实现和它们之间到底有什么区别 (一些复杂的功能我会之后发出文章,请记得关注) Filter的简单实现 字面意思:过滤器就是过滤的作用,在web开发中过滤一些我们指定的url 那么它能帮我们过滤什么呢? 那功能可就多了: 比如过拦截掉我们不需要的接口请求 修改请求(reques

  • SpringBoot定义过滤器、监听器、拦截器的方法

    一.自定义过滤器 创建一个过滤器,实现javax.servlet.Filter接口,并重写其中的init.doFilter.destory方法. package com.example.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.Se

  • Springboot过滤器禁止ip频繁访问功能实现

    在开发 Web 项目的时候,经常需要过滤器来处理一些请求,包括字符集转换什么的,记录请求日志什么的等等.在之前的 Web 开发中,我们习惯把过滤器配置到 web.xml 中,但是在 SpringBoot 中,兵没有这个配置文件,该如何操作呢? 1.编写一个过滤器: import lombok.extern.slf4j.Slf4j; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.ser

  • 手把手教你SpringBoot过滤器N种注册方式

    要说在 Spring Boot 中注册过滤器有三种方式,你都能想到哪些呢?今天松哥就来和大家聊一聊 Spring Boot 中注册过滤器的三种方式! 其实本来是想和大家聊 Spring Security 过滤器链的问题的,结果看源码看着看着就跑题了,索性就先和大家聊一聊 Spring Boot 中注册过滤器的三种方式,算是给 后面的 Spring Security 打一点基础. 1.@WebFilter 通过 @WebFilter 注解来标记一个过滤器,这种方式相信大家很容易想到.这是将 Ser

  • 手把手教你SpringBoot轻松整合Minio

    前言 使用Spring Boot 可以非常方便.快速搭建项目,使我们不用关心框架之间的兼容性,适用版本等各种问题,我们想使用任何东西,仅仅添加一个配置就可以. 提示:以下是本篇文章正文内容,下面案例可供参考 一.技术介绍 1.Minio是什么? MinIO 是一个基于Apache License v2.0开源协议的对象存储服务.它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片.视频.日志文件.备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5

  • 手把手教你SpringBoot快速集成Swagger的配置过程

    导语 相信大家无论是做前端还是做后端的,都被接口接口文档所折磨过,前端抱怨接口文档和后端给的不一致,后端抱怨写接口文档很麻烦,所以Swagger就诞生了.直接配置即可自动生成接口文档,而且提供了高效的API测试 话不多说直接开干 导入SpringBoot集成Swagger所需要的依赖 <!--web方便测试--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g

  • 手把手教你写一个vue全局注册的Toast的实现

    目录 前言: 我们先思考下面的问题: 首先: 然后: 后来: 再且: 前言: 前几天客户经理不让我用某饿了么之类的UI库做一个轻提示之类的组件,当时一想我是饿了么战士,怎么会写哪个东西,然后我就想着用个alert糊弄过去,但是不行,然后我就细琢磨,发现Vue有个非常不错的Vue.extend. 经过一番努力,我学会了,可能是以前学的时候马虎漏掉了.不过问题不大,还能肝. 我们先思考下面的问题: 在写vue项目的时候啊,我们有了初始化的根实例之后,页面之间都是通过router进行管理,组件也是通过

  • 深入Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来接收来自系统和应用中的广播.在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能:当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作:当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户

  • springboot的四种启动方式

    目录 环境准备 第一种:直接main方法启动TxDemo2Application 第二种:通过maven插件来启动 第三种打jar包来访问 第四种通过docker容器虚拟化运行 环境准备 创建工程 pom.xml内容 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="h

  • 浅谈springboot的三种启动方式

    有段时间没有写博客了,也在努力的从传统单机开发向分布式系统过度,所以再次做一些笔记,以方便日后查看. 直接进入正题吧,今天记录spring-boot项目的三种启动方式. spring-boot的启动方式主要有三种: 1. 运行带有main方法类 2. 通过命令行 java -jar 的方式 3. 通过spring-boot-plugin的方式 一.执行带有main方法类 这种方式很简单,我主要是通过idea的方式,进行执行.这种方式在启动的时候,会去自动加载classpath下的配置文件 (这里

  • 详解springboot的三种启动方式

    一:IDE 运行Application这个类的main方法 二:在springboot的应用的根目录下运行mvn spring-boot:run 三:使用mvn install 生成jar后运行 先到项目根目录 mvn install cd target java -jar xxxx.jar 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们.

  • Android BroadcastReceiver广播注册方式总结

    Android:BroadcastReceiver注册的方式分为两种: 静态注册 动态注册 1. 静态注册 在AndroidManifest.xml里通过标签声明 属性说明: <receiver android:enabled=["true" | "false"] //此broadcastReceiver能否接收其他App的发出的广播 //默认值是由receiver中有无intent-filter决定的:如果有intent-filter,默认值为true,否则

  • SpringBoot注册Filter的两种实现方式

    springboot版本:2.2.5 一.filter注册 springboot中添加filter有两种方式: 1.实现方法一 package com.example.demo.filter1; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.Servl

随机推荐