过滤器 Filter 与 拦截器 Interceptor 的区别
引言
说起 Filter 与 Interceptor 的区别,相信很多同学第一感觉就是容易、简单!
毕竟开发中这两个组件使用频率较高,用法也较简单。然后真回答起来有答不出个所以然来,场面尴尬,老丢脸了!
看着简单,一答就错,下面咱们先看结论!再做详细解说!
结论
- 底层原理不同:Filter 是 基于 函数回调 实现的; Interceptor 是基于 反射机制与动态代理 实现的。
- 使用范围不同:Filter 是 Servlet规范 的接口,依赖web容器(Tomcat等),只能在web工程中使用;Interceptor 是 Spring的组件,不依赖web容器。
- 触发时机不同:请求进入顺序: Tomcat ==> Filter ==> Servlet ==> Interceptor ==> Controller。
- 拦截范围不同:Filter 对进入容器的所有请求进行拦截;Interceptor 只会对
Controller中请求或访问static目录下的资源请求进行拦截。 - 注入bean情况不同:Filter 中能正常注入其他bean; Interceptor 在 springcontext 之前加载,而 bean 由 Spring管理,所以注册 Interceptor 前需要先手动注入 Interceptor ;
- 控制执行顺序不同:实际开发中,使用的通常是多个 Filter 或 Interceptor 组成的 链;Filter 中 拦截的核心方法是 doFilter(), Filter 直接按顺序执行;但是在 Interceptor 中存在 前置拦截方法 preHandle() 和 后置拦截方法 postHandle(),preHandle() 是顺序执行的,而 postHandle() 是反顺序执行的。
原理
函数回调
函数回调,简称回调(callback),是指通过函数参数传递到其它代码的,某一块可执行代码的引用。
Java中没有指针,不能将函数名作为参数传递,只能通过反射、直接调用、接口调用、Lambda表达式等方法来实现函数回调。这里用Lambda表达式给大家做个演示:
请求类:
public class Request{
public void send(CallBack callBack) {
System.out.println("[Request]:发送请求");
}
}
回调接口:
public interface CallBack {
void processResponse();
}
测试类:
public class Main {
public static void main(String[] args) {
Request request = new Request();
request.send(()-> System.out.println("[CallBack]:监听到请求,进行处理响应"));
}
}
注:想看看回调其他写法的可以看看这篇文章:Java回调的四种写法(反射、直接调用、接口调用、Lamda表达式) - 腾讯云开发者社区-腾讯云
过滤器Filter 与 拦截器 Interceptor 原理
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest, servletResponse);
}
}
这是一个自定义的过滤器,doFilter()方法中传入了一个接口参数FilterChain,这就是一个接口调用的函数回调。FilterChain接口中就只有一个回调方法doFilter()。
Interceptor 的原理就是一个jdk的动态代理,这里就不作演示了。
Interceptor 注入其他bean
实际开发中,通常通过实现 HandlerInterceptorAdapter 来自定义拦截器,而不是直接使用 HandlerInterceptor。

- 造成testService为null的原因就是拦截器比springcontext先加载,从下面的代码中也可以看到,拦截器是手动直接加入到注册表表中的,所以使用 @Bean 注解又手动注入了一次拦截器。此时拦截器中就可以注入其他bean了。
@Configuration
public class GlobalWebAppConfigurer implements WebMvcConfigurer {
/**
* 将拦截器添加到注册表中
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor()).addPathPatterns("/**");
}
// 手动注入拦截器
@Bean
public MyInterceptor myInterceptor(){
return new MyInterceptor();
}
}
Interceptor 执行顺序
由spring mvc的源码决定的,在核心转发器 DispatcherServlet 的 doDispatch 中,applyPreHandle()、applyPostHandle()对拦截器数组的调用顺序是相反的。具体源码等写到springmvc再分析。
过滤器 Filter 与 拦截器 Interceptor 的区别的更多相关文章
- Spring中过滤器(Filter)和拦截器(Interceptor)的区别和联系
在我们日常的开发中,我们经常会用到Filter和Interceptor.有时同一个功能.Filter可以做,Interceptor也可以做.有时就需要考虑使用哪一个比较好.这篇文章主要介绍一下,二者的 ...
- 过滤器(Filter)与拦截器(Interceptor)的区别
1 .拦截器是基于java的反射机制的,而过滤器是基于函数回调. 2 .拦截器不依赖与servlet容器,过滤器依赖与servlet容器. 3 .拦截器只能对action请求起作用,而过滤器则可以对几 ...
- 过滤器(Filter)和拦截器(Interceptor)
过滤器(Filter) Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序.它依赖于servlet容器,在实现上,基于函数回调,它可以对几乎所有请求 ...
- Java 中的过滤器Filter 和拦截器 Interceptor
1.先说拦截器 Interceptor 本项目以springboot为例: 新建 InterceptorConfig package com.opendev.mystudy.MyInterceptor ...
- Spring filter和拦截器(Interceptor)的区别和执行顺序
转载自:http://listenup.iteye.com/blog/1559553 1.Filter过滤器只过滤jsp文件不过滤action请求解决方案 解决办法:在web.xml中将filter的 ...
- 过滤器(Filter)、拦截器(Interceptor)、监听器(Listener)
一.Filter 过滤器 1.简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servle ...
- 三种实现日志过滤器的方式 (过滤器 (Filter)、拦截器(Interceptors)和切面(Aspect))
1.建立RequestWrapper类 import com.g2.order.server.utils.HttpHelper; import java.io.BufferedReader; impo ...
- 二十五、过滤器Filter,监听器Listener,拦截器Interceptor的区别
1.Servlet:运行在服务器上可以动态生成web页面.servlet的声明周期从被装入到web服务器内存,到服务器关闭结束.一般启动web服务器时会加载servelt的实例进行装入,然后初始化工作 ...
- Filter(过滤器) 和 interceptor(拦截器)的区别
Filter(过滤器) 和 interceptor(拦截器)的区别 1.拦截器是基于java反射机制的,而过滤器是基于函数回调的. 2.过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容 ...
- Java过滤器(Filter)与SpringMVC拦截器(Interceptor)之间的关系与区别
过滤器和拦截器的区别: ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤 ...
随机推荐
- golang channel底层结构和实现
一.介绍 Golang 设计模式: 不要通过共享内存来通信,而要通过通信实现内存共享 channel是基于通信顺序模型(communication sequential processes, CSP) ...
- 关于Linux中使用bc命令计算圆周率
Linux系统中,我们可以安装bc计算器用来计算pi值(π圆周率) 在玩的同时,这可以从某些方面反映出一个CPU的运算能力,在命令最前加上time即可 如果系统中没有bc命令,需要先进行安装:yum ...
- NOIP2015 普及组 洛谷P2671 求和 (数学)
一道数学题...... 采用分组的思想,我们要统计答案的数对满足两个条件:同奇偶,同颜色.所以可以按这两个要求分组. 然后就是分组处理了,对于每组(有k个数),这里面的任意两对数都是满足条件的,可推出 ...
- reportportal 集成 robotframework 自动化执行及结果可视化
前言: 最近领导想了个需求,想把目前组内在linux平台上执行的自动化脚本搞成可视化,如果是web站点相关日志可视化倒是简单了,ELK就是不错的选择,大部分可视化项目这种的,可以做的开起来很炫. 我们 ...
- 二、Kubernetes 概念介绍
一.Master Master指的是集群控制节点,在每个Kubernetes集群里都需要有一个Master来负责整个集群的管理和控制,基本上Kubernetes的所有控制命令都发给它,它负责具体的 ...
- certutil做哈希校验并下载网络文件
微软Win系统自带,不需要安装的工具,但它是CMD命令行工具,关于命令行工具的说明和使用请参考我以前的文章 Windows系统的命令行(CLI)介绍及入门使用说明 . 这个微软自带的命令行工具叫做 c ...
- 无线adb连接
使用USB数据线连接Android设备; 在dos命令行输入adb tcpip [xxxx]命令 (例如:adb tcpip 8888,xxx代表端口号); 断开USB数据线(数据线和设备断开连接 ...
- day12-Servlet02
Servlet02 6.GET和POST请求的分发处理 开发Servlet,通常编写doGet,doPost方法.来对表单的get和post请求进行分发处理 例子 在web文件夹下面创建一个html页 ...
- zk系列二:zookeeper实战之分布式统一配置获取
前面介绍了zk的一些基础知识,这篇文章主要介绍下如何在java环境下获取zk的配置信息:主要基于zk的监听器以及回调函数通过响应式编程的思想将核心代码糅合成一个工具类,几乎做到了拿来即用: 在分布式集 ...
- 从0搭建vue3组件库: Input组件
本篇文章将为我们的组件库添加一个新成员:Input组件.其中Input组件要实现的功能有: 基础用法 禁用状态 尺寸大小 输入长度 可清空 密码框 带Icon的输入框 文本域 自适应文本高度的文本域 ...