您的位置:首页 > 编程语言 > Java开发

怎样实际项目中运用责任链模式

2018-12-11 20:05 1546 查看

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() 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Spring