soul 网关中插件的定义
插件是 soul 网关的核心概念, soul 的特性都是基于插件实现的, soul 中插件的接口定义在模块 soul-plugin-api 中, 其主要的方法如下:
public interface SoulPlugin { |
execute方法定义了 soul 插件逻辑的执行入口getOrder约束接口要求了所有的实现类需要在这个接口的实现里面返回 int 类型的插件顺序, 这个顺序在组织网关的插件链的时候会决定网关请求上下文在插件处理链上的处理的顺序
组织插件链的时候会根据 order 排序, 详细的处理在 org.dromara.soul.web.configuration.SoulConfiguration#soulWebHandler 中的 final List<SoulPlugin> soulPlugins = pluginList.stream().sorted(Comparator.comparingInt(SoulPlugin::getOrder)).collect(Collectors.toList());
排好序之后的插件列表会作为 SoulWebHandler 的构造函数影响 SoulWebHandler 中处理网关请求过程中插件链中插件链的处理顺序。
named约束接口要求了所有的实现类需要在这个接口的实现里面返回插件的名称skip接口根据传入的ServerWebExchange中的网关请求上下文信息判断是否跳过一个插件的处理
soul 网关插件链处理
插件链的处理流程可以用下图描述

soul-web 模块中的 SoulWebHandler 是处理 soul 网关请求的关键类, 在它的 execute 方法中, 可以看到它会实例化 DefaultSoulPluginChain 对象后然后调用它的 execute 方法, DefaultSoulPluginChain 对象的 execute 方法如下:
|
execute 方法中使用了 Mono 对象的静态方法 defer, 注释中对 defer 方法的描述是: “Create a Mono provider that will supply a target Mono to subscribe to for each Subscriber downstream”, 也就是说当返回的Mono 对象被 subscribe 的时候才会调用 defer 方法的入参, 它的入参对象是个 Supplier。这个 Supplier 方法体的内部执行的就是插件链中插件链条的处理逻辑:
- 每次请求都会实例化一个新的
DefaultSoulPluginChain对象,多个请求的插件链互不干扰 - 一个请求执行到插件链的进度由
DefaultSoulPluginChain对象实例中的index标识 - 通过
SoulPlugin的skip方法判断是否跳过当前插件的处理- 跳过处理的方法是调用当前实例的
execute方法,因为index变量已经自增, 所以跳过处理调用当前实例的execute方法之后会处理插件链条中当前插件节点的下一个插件节点 - 如果不跳过处理, 执行插件的
execute方法, ServerWebExchange 信息和当前的插件链信息传入让插件链往下执行
- 跳过处理的方法是调用当前实例的