利用责任链模式设计一个拦截器(下)

简介: 近期在做 Cicada 的拦截器功能,正好用到了责任链模式。 这个设计模式在日常使用中频率还是挺高的,借此机会来分析分析。

用责任链模式设计一个拦截器


对于拦截器来说使用责任链模式再好不过了。


下面来看看在 Cicada 中的实现:

首先是定义了和上文 Process 接口类似的 CicadaInterceptor 抽象类:


public abstract class CicadaInterceptor {
    public boolean before(CicadaContext context,Param param) throws Exception{
        return true;
    }
    public void after(CicadaContext context,Param param) throws Exception{}
}


同时定义了一个 InterceptProcess 的客户端:



其中的 loadInterceptors() 会将所有的拦截器加入到责任链中。


再提供了两个函数分别对应了拦截前和拦截后的入口:



实际应用


现在来看看具体是怎么使用的吧。



在请求的 handle 中首先进行加载(loadInterceptors(AppConfig appConfig)),也就是初始化责任链。


接下来则是客户端的入口;调用拦截前后的入口方法即可。


由于是拦截器,那么在 before 函数中是可以对请求进行拦截的。只要返回 false 就不会继续向后处理。所以这里做了一个返回值的判断。


同时对于使用者来说只需要创建拦截器类继承 CicadaInterceptor 类即可。


这里做了一个演示,分别有两个拦截器:


  1. 记录一个业务 handle 的执行时间。


  1. after 里打印了请求参数。


  1. 同时可在第一个拦截器中返回 false 让请求被拦截。


先来做前两个试验:


这样当我请求其中一个接口时会将刚才的日志打印出来:



接下来我让打印执行时间的拦截器中拦截请求,同时输入向前端输入一段文本:



请求接口可以看到如下内容:




同时后面的请求参数也没有打印出来,说明请求确实被拦截下来。


同时我也可以调整拦截顺序,只需要在@Interceptor(order = 1) 注解中定义这个 order 属性即可(默认值是 0,越小越先执行)。


之前是打印请求参数的拦截器先执行,这次我手动将它的 order 调整为 2,而打印时间的 order 为 1 。



再次请求接口观察后台日志:



发现打印执行时间的拦截器先执行。


那这个执行执行顺序如何实现自定义配置的呢?


其实也比较简单,有以下几步:


  • 在加载拦截器时将注解里的 order 保存起来。


  • 设置拦截器到责任链中时通过反射将 order 的值保存到各个拦截器中。


  • 最终通过排序重新排列这个责任链的顺序。


贴一些核心代码。


扫描拦截器时保存 order 值:



保存 order 值到拦截器中:



重新对责任链排序:



总结


整个责任链模式已经讲完,希望对这个设计模式还不了解的朋友带来些帮助。


上文中的源码如下:




相关文章
|
4月前
|
设计模式
|
6月前
|
设计模式 JavaScript 前端开发
如何优雅的使用责任链模式?
【6月更文挑战第7天】如何优雅的使用责任链模式?
|
7月前
|
设计模式
职责链模式
职责链模式
49 0
|
7月前
|
设计模式 PHP
php设计模式--责任链模式(五)
php设计模式--责任链模式(五)
38 0
|
JavaScript 测试技术
关于责任链模式我所知道的
关于责任链模式我所知道的
87 0
|
设计模式 数据处理
我学会了,职责链模式
职责链模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。
118 0
我学会了,职责链模式
责任链模式简单介绍
责任链模式简单介绍
140 0
|
设计模式
利用责任链模式设计一个拦截器(上)
近期在做 Cicada 的拦截器功能,正好用到了责任链模式。 这个设计模式在日常使用中频率还是挺高的,借此机会来分析分析。
|
Java Nacos Sentinel
责任链模式详解(上)
责任链模式详解
239 0
责任链模式详解(上)
|
设计模式 XML 数据格式