引言

说起 Filter 与 Interceptor 的区别,相信很多同学第一感觉就是容易、简单!

毕竟开发中这两个组件使用频率较高,用法也较简单。然后真回答起来有答不出个所以然来,场面尴尬,老丢脸了!

看着简单,一答就错,下面咱们先看结论!再做详细解说!

结论

  1. 底层原理不同:Filter 是 基于 函数回调 实现的; Interceptor 是基于 反射机制与动态代理 实现的。
  2. 使用范围不同:Filter 是 Servlet规范 的接口,依赖web容器(Tomcat等),只能在web工程中使用;Interceptor 是 Spring的组件,不依赖web容器。
  3. 触发时机不同:请求进入顺序: Tomcat ==> Filter ==> Servlet ==> Interceptor ==> Controller。
  4. 拦截范围不同:Filter 对进入容器的所有请求进行拦截;Interceptor 只会对Controller中请求或访问static目录下的资源请求进行拦截。
  5. 注入bean情况不同:Filter 中能正常注入其他bean; Interceptor 在 springcontext 之前加载,而 bean 由 Spring管理,所以注册 Interceptor 前需要先手动注入 Interceptor ;
  6. 控制执行顺序不同:实际开发中,使用的通常是多个 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 的区别的更多相关文章

  1. Spring中过滤器(Filter)和拦截器(Interceptor)的区别和联系

    在我们日常的开发中,我们经常会用到Filter和Interceptor.有时同一个功能.Filter可以做,Interceptor也可以做.有时就需要考虑使用哪一个比较好.这篇文章主要介绍一下,二者的 ...

  2. 过滤器(Filter)与拦截器(Interceptor)的区别

    1 .拦截器是基于java的反射机制的,而过滤器是基于函数回调. 2 .拦截器不依赖与servlet容器,过滤器依赖与servlet容器. 3 .拦截器只能对action请求起作用,而过滤器则可以对几 ...

  3. 过滤器(Filter)和拦截器(Interceptor)

    过滤器(Filter) Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序.它依赖于servlet容器,在实现上,基于函数回调,它可以对几乎所有请求 ...

  4. Java 中的过滤器Filter 和拦截器 Interceptor

    1.先说拦截器 Interceptor 本项目以springboot为例: 新建 InterceptorConfig package com.opendev.mystudy.MyInterceptor ...

  5. Spring filter和拦截器(Interceptor)的区别和执行顺序

    转载自:http://listenup.iteye.com/blog/1559553 1.Filter过滤器只过滤jsp文件不过滤action请求解决方案 解决办法:在web.xml中将filter的 ...

  6. 过滤器(Filter)、拦截器(Interceptor)、监听器(Listener)

    一.Filter 过滤器 1.简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servle ...

  7. 三种实现日志过滤器的方式 (过滤器 (Filter)、拦截器(Interceptors)和切面(Aspect))

    1.建立RequestWrapper类 import com.g2.order.server.utils.HttpHelper; import java.io.BufferedReader; impo ...

  8. 二十五、过滤器Filter,监听器Listener,拦截器Interceptor的区别

    1.Servlet:运行在服务器上可以动态生成web页面.servlet的声明周期从被装入到web服务器内存,到服务器关闭结束.一般启动web服务器时会加载servelt的实例进行装入,然后初始化工作 ...

  9. Filter(过滤器) 和 interceptor(拦截器)的区别

    Filter(过滤器) 和 interceptor(拦截器)的区别 1.拦截器是基于java反射机制的,而过滤器是基于函数回调的. 2.过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容 ...

  10. Java过滤器(Filter)与SpringMVC拦截器(Interceptor)之间的关系与区别

    过滤器和拦截器的区别: ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤 ...

随机推荐

  1. 谣言检测(PSIN)——《Divide-and-Conquer: Post-User Interaction Network for Fake News Detection on Social Media》

    论文信息 论文标题:Divide-and-Conquer: Post-User Interaction Network for Fake News Detection on Social Media论 ...

  2. SpringBoot入门项目CRM学习过程中的报错记录(更新ing)

    在用mybatis自动生成实体类和mapper时报错..... is unrecognized or represents more than one time zone. You must conf ...

  3. BigDecimal 用法总结

    转载请注明出处: 目录 1.BigDecimal 简介 2.构造BigDecimal的对象 3.常用方法总结 4.divide方法使用 5.setScale 方法使用 6.BigDecimal 数据库 ...

  4. KVM导入Ubuntu Cloud 镜像创建虚机及调整磁盘大小

    Ubuntu Cloud Images Ubuntu官网会给各种公有云平台提供cloud镜像, 例如AWS, MS Azure, Google Cloud, 以及本地虚机环境例如 QEMU, VMwa ...

  5. redis bitmap数据结构之java对等操作

    在之前的文章中,我们有说过bitmap,bitmap在很多场景可以应用,比如黑白名单,快速判定,登录情况等等.总之,bitmap是以其高性能出名.其基本原理是一位存储一个标识,其他衍生知道咱就不说了, ...

  6. KTV和泛型(3)

    泛型除了KTV,还有一个让人比较疑惑的玩意,而且它就是用来表达疑惑的:? 虽然通过泛型已经达到我们想要的效果了,例如: List<String> list = new ArrayList& ...

  7. KubeEdge SIG AI发布首个分布式协同AI Benchmark调研

    摘要:AI Benchmark旨在衡量AI模型的性能和效能. 本文分享自华为云社区<KubeEdge SIG AI发布首个分布式协同AI Benchmark调研>,作者:KubeEdge ...

  8. How to get the return value of the setTimeout inner function in js All In One

    How to get the return value of the setTimeout inner function in js All In One 在 js 中如何获取 setTimeout ...

  9. 关于针对XSS漏洞攻击防范的一些思考

    众所周知,XSS几乎在最常见.危害最大的WEB漏洞.针对这个危害,我们应该怎么防范呢. 下面简单说一下思路. 作者:轻轻的烟雾(z281099678) 一.XSS漏洞是什么 XSS漏洞网上的资料太多, ...

  10. golang开发一个简单的grpc

    0.1.索引 https://waterflow.link/articles/1665674508275 1.什么是grpc 在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的 ...