Soul网关源码探秘《五》 - 插件链初探
Soul 网关的一大特点是使用了插件化设计思想,插件热插拔,易扩展。这其中使用了责任链的设计模式实现了 Soul 中的插件链。
若要研究插件链是如何实现的,我们先来研究一下责任链模式是什么
责任链模式(Chain of Responsibility)
维基百科中是这么定义责任链模式的:
In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects.[1] Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain.
在面向对象设计中,责任链模式是一种包含一种指令对象和一系列包含处理对象的一种设计模式。每一种处理对象包含了定义他可以处理指令对象类型的逻辑,其余的将被传递给责任链上的下一个处理对象。
责任链模式避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。责任链模式是一种对象行为型模式。
在责任链模式中引入了如下几个角色:
- Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,包含一个对其下家引用的成员。通过该引用,处理者可以连成一条链。
abstract class Handler {
//维持对下家的引用
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor=successor;
}
public abstract void handleRequest(String request);
}
- ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在处理请求之前需要进行判断,看是否符合规则,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。
class ConcreteHandler extends Handler {
public void handleRequest(String request) {
if (请求满足条件) {
//处理请求
}
this.successor.handleRequest(request); //转发请求
}
}
具体处理者是抽象处理者的子类,它具有两大作用:第一是处理请求,不同的具体处理者以不同的形式实现抽象请求处理方法handleRequest();第二是转发请求。
类型
责任链模式可分为纯的责任链模式和不纯的责任链模式两种。主要的区别是一个纯的责任链模式要求一个具体处理者对象只能在两个行为中选择一个,而在一个不纯的责任链模式中允许某个请求被一个具体处理者部分处理后再向下传递。
Soul 插件链
可以看到所有插件子类继承自 AbstractPlugin
,在这里所有插件子类相当于前文所说ConcreteHandler
,而AbstractPlugin
则相当于Handler
。
AbstractPlugin
的execute
方法中,通过if (pluginData != null && pluginData.getEnabled())
来判断是否执行某个插件的逻辑。如果没有设置使用该插件。则通过return chain.execute(exchange)
进入下一个插件的execute
方法执行逻辑。
所以将流程转入下一个插件的过程是通过参数中SoulPluginChain
的 execute
实现的。
从图中 SoulPluginChain
唯一的实现方法中可以看出,可以设置略过某个插件;当前插件流程结束后,由插件链 chain
将流程转交给下一个插件直到所有插件处理完成。
从这里也可以看出,无论请求被多少插件处理过,都会由插件链转交给下一个插件进行判断处理。所以 Soul
网关中的插件链是前文所述不纯的责任链模式这一类。
那么 plugins
是在什么时候设置的呢?继续往前追溯,发现DefaultSoulPluginChain
是私有的内部类,只能在当前类实例化使用。而实例化DefaultSoulPluginChain
的时候又是由SoulWebHandler
把plugins
传递过来的。
从下图可以看出,Spring项目启动时,SoulWebHandler
被注册为 Bean 交由 Spring 管理。在初始化SoulWebHandler
时收集所有配置的 plugin
并按照order
排序后形成 plugins
。
此时,项目启动时初始化SoulWebHandler
并初始化默认插件链中plugins
,以及当有请求时,插件链中的各个插件是如何流转的就很清晰了。
单个插件流程
在前面的分析中,我们也发现单个插件的处理流程在AbstractPlugin
的doExecute
抽象方法中,由各子类自定义实现。
下一篇文章中来探索单个插件是如何执行流程的。