浅谈责任链设计模式在框架源码中的运用

news2024/12/24 2:20:18

写在前面,该篇博文为我在部门的技术分享,所以文字记录不是特别详细。本文更像是一个大纲,由浅入深讲解责任链设计模式。

浅谈责任链设计模式在框架源码中的运用

    • 一、分享目的
    • 二、简单介绍
    • 三、逐个拆解
    • 四、源码环节
      • 1、Tomcat
      • 2、Spring MVC
      • 3、Spring AOP
      • 4、MyBatis
      • 5、HSF
      • 6、Netty
    • 五、简单实战
      • 1、日终跑批
      • 2、结算
      • 3、接收外部数据(http)
    • 六、最终总结

一、分享目的

  • 认识责任链设计模式
  • 看得懂责任链设计模式不同的写法
  • 如果有机会,可以灵活运用在项目中



二、简单介绍

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式(A->B这个过程,拆分为若干段,分别写在不同的类)

主体的对象:抽象处理者(xxxContext、xxxChain)包含众多具体处理者(xxxHandler、xxxFilter)



三、逐个拆解

初印象

  1. 数据来源
    • 项目启动阶段加载
  2. 构建形式:
    • 普通list、或者链表
  3. 拦截角度
    • 直接拦截
  4. 关联细节
    • 依次完成逻辑
  5. 影响面
    • 可大可小



四、源码环节

接下来我将通过一个小案例,并且结合上面的五个维度,依次向大家讲述框架作者们是如何实现责任链设计模式的。

项目背景:在一个使用SpringBoot构建的Web项目中,持久层使用MyBatis,Web容器使用Tomcat,RPC框架使用Dubbo/HSF

案例背景:用户前台查看id=1的数据,后台将id传给第三方服务进行查询,然后返回数据给前台,当前项目操作日志需要落库。


1、Tomcat

请求首先来到Tomcat,当前为HTTP请求,先经过传输层逻辑,再跳转到对应的应用层解析类中,最后doGet–>processRequest–>doService–>doDispatch

与之类似的,Tomcat中还有一个org.apache.catalina.Valve接口

补充:

一个是tomcat基于Servlet规范出来的Filter,一个是Tomcat内部自己私有的Filter。我们的多数据源过滤就是使用Servlet的Filter


2、Spring MVC

此时来到DispatcherServlet,该类会完成根据映射路径转发请求,最后进入controller层。下图代码为在转发逻辑前后的拦截器代码

构建形式和Tomcat中Filter形式大体相同

小细节。拦截器执行方法afterCompletion方法执行顺序。(applyPreHandle和afterCompletion更像是一对)


3、Spring AOP

Controller调用Service层方法,如果该方法被@AutoLog注解修饰,可以完成打日志的功能,该对象的构建使用到了AOP。我们都只知道AOP是动态代理,实则还有责任链。


4、MyBatis

调用Mapper接口完成操作日志落库。如果使用MyBatis做为持久层框架,会在预处理我们的SQL前(prepareStatement),根据配置文件里配置的拦截器,完成相关的拦截器功能

MyBatisPlus的乐观锁、Pagehelp、对某些特定表的操作记录操作日志等功能


5、HSF

进入Service层后,业务逻辑RPC调用其他服务接口(在此之前,被调用方接口需要将自己的接口元数据信息序列化后放入三方注册中心),调用方接口根据指定的名字去注册中心找数据。这个元数据里面就会封装相关的拦截器属性,用于调用或者被调用的时候执行。

内部框架,类比Dubbo。


6、Netty

元数据序列化完成,使用Netty进行高效传输到注册中心,并且可以接受对应的数据



五、简单实战

1、日终跑批

  1. 刷新授信
  2. 日终批量记账
  3. 生成日终分录
  4. 核算余额对账
  5. 切日

2、结算

  1. 授信处理
  2. 核心记账
  3. 生成分录
  4. 生成日间分录
  5. 发送支付

3、接收外部数据(http)

  1. 处理请求
  2. 保存日志
  3. 封装对象
  4. 业务处理
  5. 返回



六、最终总结

  1. 数据来源多:spi直接加载(HSF)、借助Spring加载(业务代码)、根据业务代码选择加载(Spring MVC)、数据库或配置文件
  2. 构建结构多:普通List(MyBatis)、单向链表(Tomcat ValveBase)、双向链表(HSF、Netty)、递归结构(Spring AOP)
  3. 拦截角度多:单纯走流程(MyBatis)、可以中途直接返回(Tomcat)、返回了但又没有完全返回(Spring MVC)
  4. 关联细节多:每一步相互独立(Tomcat Filter)、每一步相互关联(Netty)
  5. 框架影响多:简单的(MyBatis)、复杂的(Netty)



小思考:我们不乏看到责任链的呈现形式是递归调用的,那么请问我装饰者模式不停的向上装饰自己(MyBatis的Cache),或者说我使用代理模式不断的代理之前的自己有什么区别?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/87189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL基础】什么是MySQL约束?什么是主键约束?

目录 一、什么是MySQL约束? 二、MySQL约束有什么作用? 三、MySQL约束常见七大类? 主键约束(primary key) PK 1.概念 2.主键约束的相关操作 添加单列主键 添加多列主键(联合主键) 通过修改表结构添加主键 删除主键 💟 创…

【Notebook系列第十三期】基于多模型推理任务的车辆特征识别

在之前的课程中,我们分享的推理任务大部分都只由一个模型构成,但在真实的业务场景下,往往需要我们将多个模型放在一起去运行,才能获取到这个任务的最终预期结果。 因此,本次分享将通过一个简单的示例演示如何使用 Ope…

12月13日(第11天)

腾讯云上通过面板开放端口,不起作用,解决办法:手动在服务器上开放,参考文章地址:在腾讯云控制台下配置防火墙端口无效 直接关闭防火墙是最简单的,systemctl stop firewalld,然后再再腾讯云上打开…

解决端口被占用的方法(查看端口和关闭端口)

目录 前言必读 一.简介 二、解决办法 1.查看该端口是否被占用 2.关闭占用该端口的进程 前言必读 读者手册(必读)_云边的快乐猫的博客-CSDN博客 一.简介 在使用各种端口时候经常会出现端口被占用导致代码程序无法执行或者执行错误。一般都是由于该端…

DataGear 4.3.0 发布,数据可视化分析平台

DataGear 4.3.0 发布,增强图表和看板功能,具体更新内容如下: 新增:看板模板新增dg-dashboard-auto-render属性,用于控制看板是否自动渲染;新增:看板模版新增dg-dashboard-code属性,…

Spring Batch 批处理-作业参数设置与获取

引言 书接上篇Spring Batch批处理-作业Job简介,上篇带小伙伴们了解色作业Job对象,那这篇就看一下作业参数是啥一回事,同时要怎么设置参数并获取参数的。 JobParameters 前面提到,作业的启动条件是作业名称 识别参数&#xff0…

MQ消息中间件

MQ消息中间件1、应用场景1、流量削峰2、应用解耦3、异步处理2、MQ分类1、ActiveMQ2、kafka3、RocketMQ4、RabbitMQ3、RabbitMQ详解3.1、核心概念3.2 RabbitMQ基本知识点3.3消息发布确认3.4 交换机1、应用场景 1、流量削峰 将访问的大流量通过消息队列做缓冲,我们可…

二叉树-二叉树的基础遍历(3)

二叉树的遍历的三种方式 1.前序遍历; 先访问根结点,然后再访问左子树,最后访问右子树 2.中序遍历; 先访问左子树,中间访问根节点,最后访问右子树 3.后序遍历; 先访问左子树,再访问右…

PicoRV32 笔记 05

接口信号 PicoRV32 提供一个本地存储器接口,Native Memory Interface。 本地存储器接口采用 valid-ready握手信号。这种机制在axi总线中使用相同,能够实现流控, 和axi总线不同点,PicoRV32本地接口使用一组valid-ready信号&…

什么是SWDM4和100G QSFP28 SWDM4光模块?

随着OM5多模光纤(MMF)的推广和40G或100G数据中心传输网络的大规模部署,SWDM技术逐渐进入人们的视野并开始得到应用。那么,什么是SWDM4呢?什么是100G SWDM4光模块?它们的优势是什么?跟着易天光通信ETU-LINK看下面的文字…

十、原型、原型链、闭包和立即执行函数、插件开发初始

十、原型、原型链、闭包和立即执行函数、插件开发初始 原型 什么是原型(prototype)? 无论何时,只要创建一个函数,就会按照特定的规则为这个函数创建一个prototype属性,指向原型对象。 function Car(){}…

Vue入门与指令

Vue入门 1.1、MVVM编程思想 MVVM:页面输入改变数据,数据改变影响页面数据展示与渲染。 M(model):普通的javascript数据对象。 V(view):前端展示页面。 VM(ViewModel&…

Jmeter初了解-接口并发测试

Jmeter初了解-接口并发测试 介绍 我们在开发的时候,经常会需要进行接口压力测试,确定接口运行的稳定情况 这里我们就使用java开发的测试工具Jmeter来进行测试。 Jmeter 官网地址 Apache JMeter™应用程序是开源软件,是一个 100% 纯 Jav…

Pytorch安装详细过程及遇到的问题解决

一、Aanconda的安装 可以参考笔者的这篇博客:Anaconda安装详细教程 二、准备工作 1、查看本机的python的版本(本机python解释器版本为3.8.5) 2、单击启动Anaconda Prompt创建新虚拟环境 3、在Anaconda Prompt依次执行以下命令,创建名字为pytorch的虚拟…

nn.Embedding使用

nn.Embedding是一种词嵌入的方式,跟one-hot相似但又不同,会生成低维稠密向量,但是初始是随机化的,需要根据模型训练时进行调节,若使用预训练词向量模型会比较好。 1. one-hot one-hot是给定每个单词一个索引&#xf…

概论_第4章__方差D(X)的定义和性质

一 定义 通常以此公式来计算: 就是说: 方差 X的平方再求期望 —— X的期望的平方 即 括号里面的平方的期望减去期望的平方, 怎样求期望点击:概论_第4章__期望的定义和性质 注意: 方差不可能为负数。 2. …

如何快速拥有自己的虚拟形象?

元宇宙(Metaverse),是人类运用数字技术构建的,由现实世界映射或超越现实世界,可与现实世界交互的虚拟世界,具备新型社会体系的数字生活空间。 可见元宇宙第一步是创建专属虚拟形象,但创建3D虚拟…

Android入门第45天-手工发送一个BroadCast

简介 上一篇我们讲了简单的动态BroadCast,今天我们通过手工来发送一条BroadCast进一步来了解BroadCast。 在上一篇里我们使用BroadCast监听网络状态,今天我们要完成的是自己发一条自自己的消息来触发BroadCast Receiver。 设计 为了让Receiver收听到…

蓝牙耳机无延迟哪款好?适合打游戏的无线蓝牙耳机

手机可以说是人手必备,随声得还有蓝牙耳机,随着3.5耳机孔得消失,蓝牙耳机可以说是现在得主流,无论哪个年龄段都可以佩戴蓝牙耳机,日常听歌、追剧,和朋友玩游戏佩戴蓝牙耳机,已经成为一种生活方式…

mybatis06:MyBatis的多表操作

目录 1.一对一关系 2.一对多查询 3.多对多查询 4例题演示 ​5.知识小结 1.一对一关系 2.一对多查询 3.多对多查询 4例题演示 前置准备 对应的依赖 <dependencies><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId&…