pipeline java_架构模式:pipeline

知名的 Pipeline 模式

unix 的 pipeline

cat helloworld.txt | grep "hello world" | rev | > output.txt

读取文本内容,并过滤 “hello world”,然后反转字符,将最终结果输出到 output.txt

Web 框架中间件

Laravel 中的管道

Laravel 在框架中很多地方都使用了管道,最常见的就是中间件实现。当请求最终到达控制器动作被处理前,会经过一系列的中间件。每个中间件都有一个独立的职责,例如,设置 Cookie / 判断是否登录以及阻止 CSRF 攻击等。

每个阶段都会对请求进行处理,如果请求通过就会被传递给下一个处理,不通过就会返回相应的 HTTP 响应。

其实何止是 Laravel,Python 中的 Django 同样如此。

9df9f58fbd32

struct.png

也就是说,每一个请求都是先通过中间件的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其他中间件,如果返回一个 HttpResponse,就处理终止,返回到页面上。Django 中把中间件叫做 hook(钩子)。

struct2

9df9f58fbd32

struct2.png

中间件,完整链路。所谓的中间件不就是 Pipeline 模式吗?

Pipeline 的特点

管道就像一个流水线,把复杂的问题的解决方案分解成一个个处理单元,然后依次处理,前一个处理单元的结果也是第二个模块的输出。

这些处理步骤通常会放在一个数组里,方便迭代这个数组时顺序执行

Pipeline 结构

Pipeline的类模型由 Pipeline/ Valve/ Context 组成。Pipeline 代表执行流,

Valve代表执行流中的一个节点,Context 是执行时的上下文信息,它一般由两部分组成:request/response + 当前流的执行状态。

有的系统只能有一个 Pipeline, 有的则允许配多个。在 Struct2 中,一个 interceptor 的组合,就代表一个 Pipeline;多种组合,意味着多个 Pipeline.

Pipeline 用法

有的 Pipeline 流是在同一个层次上,每个 valve 处理的 request / response 对象是同质的。比如 servlet filter 和各种 MVC 框架,所处理的事情都是 web 层,所处理的 context 对象就是 http request 或者框架自定义的 javabean。

有的 pipeline 流则是纵向的,从上层流到下层,或从下层流到上层,这时每个 valve 所处理的 request / response 对象一般是异构的。协议栈就是个典型的例子:下层 valve 处理字节流,上层处理字符流。不过,为了适应 pipeline 的架构,这些异构的 context 对象必须有共同的基类,并且把这个基类作为各个 valve 的输入参数。

从请求处理的角度来说,Pipeline 可以代表整个执行流,也可以用作请求被最终处理前的 Interceptor. Webx, netty 中的 Pipeline 会将最有一个 Valve 作为请求处理者(一般称为 Request Handler), 而 servlet filter 和 struct2 interceptor 只作为请求拦截、加工,真正处理请求的是 servlet 和 action

pipeline 程序流

一个完整的 Pipeline 执行流一般是一个环路:Valve1 => Valve2 => Valve3 => Valve2 => Valve1, 从拦截的角度讲,valve 既是前置拦截(下一个 valve 执行前),又是后置拦截(下一个 valve 执行后)

为了达到前后双拦截的目标,程序有两种方法。有一种是使用了 foreach 方法分别执行每个拦截器的前置拦截方法,然后又以相反的顺序分别执行每个拦截器的后置拦截方法。这种方法比较直观,Spring MVC Interceptor 就是这种。

主流的拦截做法,把一个 valve 的执行嵌套在前一个 valve 的执行里面;每个 valve 的执行会有一句"nextValve.invoke()", 然后在这句代码前后做一些拦截。这种方式有点费解,而且由于嵌套过多容易造成比较深的调用栈;不过它有一个好处:更方便地中断执行并处理异常。

执行流程必须提供中断机制和异常处理机制,比如鉴权 filter 发现用户未登录时需立即返回 403 并中断流,当一个 valve 出现异常时这个异常需要被捕捉、处理。如果 Valve 是嵌套执行的,这些机制会很方便实现:鉴权 filter 发现用户未登录,不调用 nextValue.invoke() 即可中断 pipeline;至于异常处理,Struct2 默认使用 ExceptionMappingInterceptor 作为 Pipeline 中的第一个 valve,它会把 nextIntercetpor.invoke() 放在自己 try/catch 中。如果 valve 不是嵌套执行,而是由pipeline 通过 forEach 编排执行的,那么这些非正常流的“扳道工”职责必须由 pipeline 自己来承担,这可能会使 pipeline 不够精简;如果来了新的逻辑(比如异步执行),又得改 pipeline,导致 pipeline 不太稳定。

pipeline 设计模式

一个 pipeline 结构可以做成一个单例,另外做一个 PipelineContext 代表 Pipeline 当前的执行流,至于 Valve,它相当于 stateless service 做成单例即可。

Pipeline 的优点

对于每个处理单元又可以打补丁,做监听。(这就是切面编程了)

这些处理步骤的代码还可以被其他不同的解决方案复用;

在复杂进程中添加、移除和替换子任务非常轻松。

Pipeline 的使用场景

参考文件

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

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

相关文章

MacOS 系统使用命令安装软件包

文章目录 使用 Homebrew 安装软件包先安装 Homebrew使用命令 brew 安装软件包使用命令 installer 安装 pkg 软件包使用命令安装 dmg 格式的软件包包含普通的应用程序文件的 dmg 文件如何使用命令完成安装呢?包含 pkg 安装程序的 dmg 文件又该如何通过命令完成安装呢?Linux 操…

身份证验证 校验码_用户身份验证最佳做法清单

身份证验证 校验码用户身份验证是每个Web应用程序共享的功能。 我们已经实施了很多次了,所以早就应该完善它了。 然而,错误无时无刻不在。 造成这种情况的部分原因是,可能出错的事情列表很长。 您可能会错误地存储密码,可能会具有…

mysql查询不确定的信息_mysql 07.18

1.索引搜索引导,索引是一个特殊的数据结构,期存储的是数据的关键信息与详细详细的位置对应关系。目的:加速查询。索引的影响:不是说拥有索引就能加速,得看你的查询语句有没有正确使用索引,索引也需要占用额…

MacOS 常用命令汇总

文章目录设置环境变量列出所有可以更新的软件包直接更新所有可以更新的软件包打包压缩文件忽略 Mac OS 文件系统中的扩展属性忽略 Mac OS 专有的隐藏文件创建 DMG 格式的文件修改 DMG 文件的大小修改 DMG 格式中的加密口令挂载 DMG 格式的文件推出 DMG 文件将 ISO 格式的文件转…

java多功能钟_Java 11将包含更多功能

java多功能钟Java 11即将发布的功能是什么?它与Java 9和10有何不同? Java 10可能是新手,但现在该谈论Java 11了。Oracle迈向更快的发布周期意味着更多的特性和功能以比以往更快的速度出现。 尽管距离Java 11发行还有六个月的时间&#xff0…

MacOS 好用的插件和图形界面程序

文章目录文件预览插件OS X 图形界面程序文件预览插件 有些插件可以让 Mac 上的文件预览更有效,比如语法高亮、markdown 渲染、json 预览等。 $ brew cask install qlcolorcode $ brew cask install qlstephen $ brew cask install qlmarkdown $ brew cask install…

java 线程安全性_我如何测试Java类的线程安全性

java 线程安全性我在最近的一次网络研讨会中谈到了这个问题,现在是时候以书面形式进行解释了。 线程安全是Java等语言/平台中类的重要品质,在Java中我们经常在线程之间共享对象。 缺乏线程安全性导致的问题很难调试,因为它们是零星的&#xf…

java asin_Java asin()方法

Java asin()方法asin() 方法用于返回指定double类型参数的反正弦值。语法doubleasin(doubled)参数 d -- 任何原生数据类型。返回值返回指定double类型参数的反正弦值。实例public class Test{public static void main(String args[]){double degrees 45.0;double radians Mat…

MacOS 的软件包管理工具 HomeBrew 详解

文章目录一、软件介绍二、安装 Homebrew使用 Ruby 或者 Shell 脚本安装手动 clone 安装三、卸载 Homebrew四、Homebrew 安装目录五、安装包所在位置六、程序安装目录七、软件版本切换八、清除旧版本文件九、brew 命令汇总安装、升级和删除软件包查看和检验软件包参考示例服务相…

java中的深度克隆浅克隆_了解Java中的可克隆接口

java中的深度克隆浅克隆什么是对象克隆? 对象克隆是生成具有不同名称的对象的精确字段到字段副本的过程。 克隆的对象在内存中有自己的空间,可在其中复制原始对象的内容。 这就是为什么在克隆后更改原始对象的内容时,所做的更改不会反映在克隆…

python env_#!/usr/bin/env python 有什么用?

我们经常会在别人的脚本或者项目的入口文件里看到第一行是下面这样#!/usr/bin/python或者这样#!/usr/bin/env python那么他们有什么用呢?要理解它,得把这一行语句拆成两部分。第一部分是 #!第二部分是 /usr/bin/python 或者 /usr/bin/env python关于 #! …

MacBook(macOS) 如何安装 Homebrew Cask(作废)

文章目录重要通知(不要再去安装 Homebrew Cask 了)Homebrew Cask 简介相关文件和目录Homebrew Cask 安装使用命令下载安装直接从官网下载安装包利用国内源手动 clone下载(推荐)Homebrew Cask 换源重要通知(不要再去安装…

java.io.file()_JAVA基础知识之IO-File类

File类介绍File是java.io包下面的一个类,代表与平台无关的文件或者目录。JAVA中,无论文件还是目录,都可以看作File类的一个对象。File类能对文件或目录新建,删除,获取属性等操作,但是不能直接操作文件内容(…

netflix 模式创新_创新设计模式:单例模式

netflix 模式创新单例设计模式是一种软件设计模式,用于将类的实例化限制为一个对象。 与其他创建设计模式(例如抽象工厂 , 工厂和构建器模式)相比,单例将创建一个对象,但也将负责,因此该对象只…

美式英语 [t] 的发音

爆破音 true [t],发真实的 t。 单词的开始处重读音节的开始处,且前面没有跟着清辅音 [s] held 住不发声 叫法很多,声门塞音、吞音、喉塞(s)音、stop [t],held [t],不爆破的 [t]。 发音的口…

设计模式 原型模式_创新设计模式:原型模式

设计模式 原型模式原型模式用于创建对象的副本。 这种模式非常有用,特别是当从头开始创建对象的成本很高时。 与builder , factory和abstract factory模式相比,它不会从头开始创建对象,而是会克隆/重新创建它。 与单例模式相比&a…

java file 对象_Java里File对象的问题。

Java里File对象的问题。关注:282 答案:2 mip版解决时间 2021-02-02 07:14提问者鉨瞞着所囿亾,爱着誰2021-02-01 08:59import java.io.*;在此基础上怎么修改呢? 谢谢啦最佳答案二级知识专家山河已春2021-02-01 10:06import java.io.*;class JavaFileLis…

美式英语中 [d] 的特别发音

闪音 flap [d],fast [d],闪音 [d] 发音口腔部位说明:舌尖快速拍打上齿龈后,快速释放,轻快拍打 [d] 在两个元音之间发成 fast [d],非重读音节在元音和 [l] 之间发成 fast [d],非重读音节在[r]…

netflix 模式创新_创新设计模式:工厂模式

netflix 模式创新以前,我们对创建模式进行了介绍,并使用抽象工厂模式来创建对象族。 下一个模式是Factory模式 。 当涉及到Java时,工厂模式是最常用的模式之一。 那么工厂模式到底是什么呢? 工厂模式处理创建对象而不指定确切的…

g++ 编译mysql动态库_Linux下g++编译以及使用静态库和动态库的方法详解

下面小编就为大家带来一篇Linux下g编译与使用静态库和动态库的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧在windows环境下,我们通常在IDE如VS的工程中开发C项目,对于生成和使用静态库(*.…