1 模式概要
1.1 简介
- 责任链模式为请求创建一个接收者对象链,每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把请求传给下一个接收者,依此类推
- 责任链模式避免了请求的发送者和接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
1.2 责任链模式优缺点
优点
降低耦合度。它将请求的发送者和接收者解耦
简化了对象,使得对象不需要知道链的结构
增强给对象指派职责的灵活性,允许动态地新增或者删除责任链
增加新的请求处理类方便
缺点
不能保证请求一定被接收;
系统性能将受到一定影响,调试时不方便,可能会造成循环调用
2 模式结构
2.1 对象定义
Handler(抽象处理者) : 定义一个处理请求的接口,提供对后续处理者的引用
ConcreteHandler(具体处理者) : 抽象处理者的子类,处理用户请求,可选将请求处理掉还是传给下家;在具体处理者中可以访问链中下一个对象,以便请求的转发
2.2 类图及设计
责任链
代码详解:
抽象处理者
具体处理者
在当前处理者对象无法处理时,将执行权传给下一个处理者对象
Client 客户端调用
ifelse
2.3 适用场景:
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定
- 在不明确指定接收者的情况下,向多个对象中的某一个对象提交一个请求
- 可动态指定一组对象的处理请求
3 Spring中的过滤器
我们来分析Spring中Filter的 加载流程和执行流程
3.1 初始化流程
初始化过滤器加载数据流如下:
filter初始化加载时序图
关键性代码
configure()
不管是数据走哪里,最终会通过 System.arraycopy 数组扩容,增加过滤器信息到 private FilterMap[] array
这个数组中。
最后调用StandardContext类中的 filterStart()
方法完成过滤器的初始化
3.2 执行过程
主要分两步, 创建过滤器责任链 和 执行责任链
3.2.1 创建过程
创建filterChain方法主要在 ApplicationFilterFactory.createFilterChain(request, wrapper, servlet)
中,部分代码讲解:
在StandardWrapperValue类的 invoke()
方法中调用ApplicationFilterChai类的 createFilterChain()
方法
在ApplicationFilterChai类的 createFilterChain()
方法中调用ApplicationFilterChain类的 addFilter()
方法
在ApplicationFilterChain类的 addFilter()
方法中给ApplicationFilterConfig数组赋值
生成调用链
3.2.2 执行责任链
调用ApplicationFilterChain的 doFilter()
方法中最后会调用一个 internalDoFilter()
方法,目的就是执行ApplicationFilterChain中的全部过滤器,从代码中可以发现它调用了 doFilter
,而在 doFilter
又会调用 internalDoFilter
从而使所有Filter都得以调用
这样,一个完整的过滤器链就形成,然后进行调用
4 项目中的实际运用
业务场景
我们在项目中使用了阿里的MQ消息中间件,来加快请求的响应时间和异步解耦处理。RocktMQ主要可以按Topic来分区,然后按Tag分组,不同的业务区分不同的 tag
比如: 在此我向大家推荐一个架构学习交流裙。交流学习裙号:687810532,里面会分享一些资深架构师录制的视频录像
短信类的消息 messageTag
手机推送消息 pushTag
延时任务消息 delayTag
等等。。。
常规写法
ifelse
具体设计方案如下:
设计UML类图
类图
抽象公共监听器 ,主要用到了单例模式获取常量
具体监听器 ,监听器主要用于MQ监听消费Topic
consume()
抽象处理者
具体处理者 :推送消息Handler
具体处理者 :延时订单处理Handler
模式工厂 HandlerFactory
getHandlerResponsibilityChain()
客户端调用
getHandlerResponsibilityChain()