63 | 职责链模式(下):框架中常用的过滤器、拦截器是如何实现的?
王争
该思维导图由 AI 生成,仅供参考
上一节课,我们学习职责链模式的原理与实现,并且通过一个敏感词过滤框架的例子,展示了职责链模式的设计意图。本质上来说,它跟大部分设计模式一样,都是为了解耦代码,应对代码的复杂性,让代码满足开闭原则,提高代码的可扩展性。
除此之外,我们还提到,职责链模式常用在框架的开发中,为框架提供扩展点,让框架的使用者在不修改框架源码的情况下,基于扩展点添加新的功能。实际上,更具体点来说,职责链模式最常用来开发框架的过滤器和拦截器。今天,我们就通过 Servlet Filter、Spring Interceptor 这两个 Java 开发中常用的组件,来具体讲讲它在框架开发中的应用。
话不多说,让我们正式开始今天的学习吧!
Servlet Filter
Servlet Filter 是 Java Servlet 规范中定义的组件,翻译成中文就是过滤器,它可以实现对 HTTP 请求的过滤功能,比如鉴权、限流、记录日志、验证参数等等。因为它是 Servlet 规范的一部分,所以,只要是支持 Servlet 的 Web 容器(比如,Tomcat、Jetty 等),都支持过滤器功能。为了帮助你理解,我画了一张示意图阐述它的工作原理,如下所示。
在实际项目中,我们该如何使用 Servlet Filter 呢?我写了一个简单的示例代码,如下所示。添加一个过滤器,我们只需要定义一个实现 javax.servlet.Filter 接口的过滤器类,并且将它配置在 web.xml 配置文件中。Web 容器启动的时候,会读取 web.xml 中的配置,创建过滤器对象。当有请求到来的时候,会先经过过滤器,然后才由 Servlet 来处理。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入介绍了Java开发中常用的过滤器和拦截器的实现方式,重点讲解了Servlet Filter和Spring Interceptor。通过示例代码和源码剖析,详细解释了它们的工作原理和底层实现,以及如何利用职责链模式实现了良好的扩展性。文章强调了职责链模式在框架开发中的重要性,以及如何实现对扩展开放、对修改关闭的设计原则。此外,还提出了在项目开发中选择AOP、Servlet Filter、Spring Interceptor来实现访问控制功能时的参考标准,并引出了其他职责链模式的实际应用案例。整体而言,本文为读者提供了深入了解过滤器和拦截器实现方式的重要知识,以及在框架开发中如何应用职责链模式的指导。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》,新⼈⾸单¥98
《设计模式之美》,新⼈⾸单¥98
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(64)
- 最新
- 精选
- 万历十五年三者应用范围不同: web filter 作用于容器,应用范围影响最大;spring interceptor 作用于框架,范围影响适中;aop 作用于业务逻辑,精细化处理,范围影响最小。
作者回复: 嗯嗯 ������
2020-11-286108 - cricket1981Filter 可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息; Interceptor 可以拿到你请求的控制器和方法,却拿不到请求方法的参数; Aop 可以拿到方法的参数,但是却拿不到http请求和响应的对象2020-03-2720176
- 常清静针对问题1而言,其实要实现一个鉴权的过滤器,通过以上3种方式都是可以去实现的,然而从粒度,场景,和方式上边有有所区别,主要采取用哪个,还是有业务来决定去用,没有统一的参考标准。比如要对所有的web接口,进行统一的权限处理,不需要区分动作,写或者读,所有一视同仁,这种情况下,servlet的更加适合。针对一些存在状态的,比如做一些统一的去参数转换,cookie转uid之类,以及通用检验uid是否符合当前权限,则很用mvc较好,而aop粒度就可以分的更加细致了,在一些更新需要,查询不需要的,如分控,日志记录等,就比较适合2020-03-27162
- webminAOP、Servlet Filter、Spring Interceptor这三者可以从不同权限检查的范围大小的视角来应用: 1. Servlet Filter 运维部门需要对只供内部访问的服务进行IP限制或访问审查时,在容器这一层增加一个Filter,在发布时发布系统自动加挂这个Filter,这样对上层应用就是透明的,内网IP地址段增减或审查规则调整都不需要上层应用的开发人员去关心。 2. Spring Interceptor 由框架或基础服务部门来提供的微服务间相互调用的授权检查时,可以提供统一的SDK,由程序员在需要的服务上配置。 3. AOP 业务应用内权限检查,可以把权限检查在统一模块中实现,通过配置由AOP加插拦截检查。2020-03-29157
- 小晏子首先需要明确“访问控制功能”的粒度,如果访问控制功能要精确到每个请求,那么要使用AOP,AOP可以配置每个controller的访问权限。而Spring interceptor和servlet filter的粒度会粗一些,控制HttpRequest, HttpResponse的访问。另外servlet filter不能够使用 Spring 容器资源,只能在容器(如tomcat)启动时调用一次,而Spring Interceptor是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象,例如 Service对象、数据源、事务管理等,通过IoC注入到Interceptor即可。相比较而言,Spring interceptor更灵活一些。2020-03-27228
- 楊_宵夜针对问题1,一把泪水想起了项目中的坑. 个人觉得最大的不同还是生效粒度的问题. 1. Servlet Filter是针对Servlet容器里的方法都能生效. 就是说Servlet容器里就算要把Spring换成别的框架,鉴权代码依然能生效. 2. Spring开头的就只能在Spring中生效, 2.1. 但更好还是在interceptor,因为interceptor天然的设计背景就是[在请求前,在相应后.] 2.2. 如果用AOP实现,就很依赖于AOP的pointcut设置,一不小心就会在[一次请求响应里]执行了[多次重复的鉴权服务]……2020-03-2920
- 筱乐乐哦1、个人感觉权限的话,属于api的调用,应该放在调用链比较靠前的位置,早发现早处理,所以用Servlet Filter会更好一些吧,如果是rpc层的话,例如dubbo,就需要 在实现filter的时候通过order吧filter得优先级提高一些,让这个filter先执行,个人感觉哈 2、Dubbo Filter的核心处理逻辑在ProtocolFilterWrapper类下的buildInvokerChain这个方法中,属于把所有的filter的类对象搞成一个list,通过遍历list去调用所有的filter,Netty ChannelPipeline我记得是一个双向链表,pipeline 中的节点的数据结构是 ChannelHandlerContext 类,每个 ChannelHandlerContext 包含一个 ChannelHandler这种,支持从头尾开始传播事件,也就是触发调用,也可以从中间节点进行调用,入栈(read)是从head开始传播,也就是开始依次调用,出栈(write)是从tail开始传播,倒着调用。感觉算是对责任链的一个拓展使用,记不清了,得去看看代码,如果说错了,欢迎指点2020-03-27318
- xk_课后题1,当然是全部都是用啊。 filter,可以控制所有的请求,用来处理网络攻击什么的。 interceptor可以控制用户和非用户的登录啊。 AOP可以控制用户角色对方方法的访问权限。 详情请见shiro,或者spring security。2020-04-2613
- 鹤涵Servlet Fillter,Spring Interceptor,Spring AOP三者粒度是越来越细的。根据业务场景的覆盖度选择。 1. 比如限流就可以在Filter层去做,因为全局都需要限流防止服务被压垮。 2. 用户是否登录权限等可以使用Interceptor做。 3. 细粒度到类或者方法的控制使用AOP去做,比如日志 事务 方法级别权限。2020-12-3011
- Geek_3e636e一个请求从客户端到服务端再到响应,假设Filter、Interceptor、AOP都存在,经过的路径大概是:请求->Filter->Interceptor->AOP->核心业务处理->AOP->Interceptor->Filter->响应。 Filter、Interceptor、 AOP在不同的节点所能感知到的数据状态都是不同的,姑且理解为域不同吧,要实现权限访问控制,肯定是在到达核心业务前植入权限控制逻辑,那就在“请求->Filter->Interceptor->AOP->核心业务处理”。 权限控制逻辑需要三个核心属性:资源、角色、角色资源映射。资源:一般我们用uri来标识某一个资源,或者可以通过注解等方式在方法上声明一个资源标识;角色和角色资源映射一般通过读取Session获取。那么权限控制逻辑放在那里取决于哪里可以拿到这两个信息?理论上角色和角色资源映射在哪里都可以读取到的。就看资源怎么表示了,如果你的资源是标识的servlet,那就通过Filter控制,如果你的资源是标识的Controller,可以在Interceptor控制,如果你的资源是标识的很深层的方法,可以在AOP控制2020-12-187
收起评论