万字+28张图带你探秘小而美的规则引擎框架LiteFlow(七)

pivoteic
发布于 2022-6-17 16:55
浏览
0收藏

 

首先从DataBus中获取一个Slot,也就是当前业务执行的上下文。之后从FlowBus中获取需要执行的Chain,最后分别调用了Chain的executePre、execute、executeFinally方法,其实不用看也知道这些方法干了什么,其实就是调用不同的Condition中Node方法。

 

executePre和executeFinally方法

万字+28张图带你探秘小而美的规则引擎框架LiteFlow(七)-鸿蒙开发者社区

这两个方法最后调用的是同一个方法,就是分别找到PreCondition和FinallyCondition,取出里面的Node节点,执行excute方法。

 

这里有重点说明一下,其实在Condition中存的不是直接的Node,而是Executable,Executable的有两个实现,一个就是我们所说的Node,还有一个就是我们一直说的Chain,为了方便大家理解,我一直说的是Node,其实这里的Executable是有可能为Chain的,取决于规则的配置。当是一个Chain的时候,其实就是一个嵌套的子流程,也就是在一个流程中嵌套另一个流程的意思,大家注意一下就行了,其实不论怎么嵌套,流程执行到最后一定是Node,因为如果是Chain,那么还会继续执行,不会停止,只有最后一个流程的Executable都是Node的时候流程才能执行完。

 

executePre和executeFinally方法说完之后,看一看execute方法的实现。

万字+28张图带你探秘小而美的规则引擎框架LiteFlow(七)-鸿蒙开发者社区

execute方法主要是判断Condition的类型,然后判断是ThenCondition还是WhenCondition,ThenCondition的话其实也就是拿出Node直接执行,如果是WhenCondition的话,其实就是并行执行每个Node节点。这也是ThenCondition和WhenCondition的主要区别。

 

画图总结一下Chain的执行流程

万字+28张图带你探秘小而美的规则引擎框架LiteFlow(七)-鸿蒙开发者社区

4)Node的执行流程

 

从上面我们可以看出,Chain的执行其实最终都是交给Node来执行的,只不过是不同阶段调用不同的Node而已,其实最终也就是会调用Node的execute方法,所以我们就来着重看一下Node的execute方法。

万字+28张图带你探秘小而美的规则引擎框架LiteFlow(七)-鸿蒙开发者社区

instance就是NodeComponent对象,也就是我们自定义实现的节点对象,好家伙,终于要执行到业务了。有人可能好奇NodeComponent是如何设置到Node对象中的,其实就是在往FlowBus添加Node的时候设置的,不清楚的小伙伴可以翻一下那块相关的源码,在解析xml那块我有说过。

 

先调用NodeComponent的isAccess方法来判断业务要不要执行,默认是true,你可以重写这个方法,自己根据其它节点执行的情况来判断当前业务的节点要不要执行,因为Slot是公共的,每个业务节点的执行结果可以放在Slot中。

 

随后通过这个方法获取了NodeExecutor,NodeExecutor可以通过execute方法来执行NodeComponent的,也就是来执行业务的,NodeExecutor默认是使用DefaultNodeExecutor子类的,当然你也可以自定义NodeExecutor来执行NodeComponent

NodeExecutor nodeExecutor = NodeExecutorHelper.loadInstance().buildNodeExecutor(instance.getNodeExecutorClass());

 

DefaultNodeExecutor的execute方法也是直接调用父类NodeExecutor的execute方法,接下来我们来看一下NodeExecutor的execute方法。

万字+28张图带你探秘小而美的规则引擎框架LiteFlow(七)-鸿蒙开发者社区

从这个方法的实现我们可以看出,LiteFlow对于业务的执行是支持重试功能的,但是不论怎么重试,最终一定调用的是NodeComponent的execute方法。

 

进入NodeComponent的execute方法

万字+28张图带你探秘小而美的规则引擎框架LiteFlow(七)-鸿蒙开发者社区

红框圈出来的,就是核心代码,self是一个变量,指的是当前这个NodeComponent对象,所以就直接调用当前这个NodeComponent的process方法,也就是用来执行业务的方法。

 

在执行NodeComponent的process方法前后其实有回调的,也就是可以实现拦截的效果,在Spring环境中会生效。

 

至于这里为什么要使用self变量而不是直接使用this,其实源码也有注释,简单点说就是如果process方法被动态代理了,那么直接使用this的话,动态代理会不生效,所以为了防止动态代理不生效,就单独使用了self变量来引用自己。至于为什么不生效,这是属于Spring的范畴了,这里就不过多赘述了。

 

其实到这里,一个Node就执行完成了,Node的执行其实就是在执行NodeComponent,而NodeComponent其实最终是交给NodeExecutor来执行的。

万字+28张图带你探秘小而美的规则引擎框架LiteFlow(七)-鸿蒙开发者社区

每个Condition中的Node执行完之后,就将Slot返回,这样就能在调用方就能通过Slot拿到整个流程的执行结果了。

 

到这里,其实核心流程源码剖析就完成了,总的来说就是将规则配置文件翻译成代码,生成Node和Chain,然后通过调用Chain来执行业务流程,最终其实就是执行我们实现的NodeComponent的process方法。

 

最终画一张图来总结整个核心源码。

万字+28张图带你探秘小而美的规则引擎框架LiteFlow(七)-鸿蒙开发者社区

图中我省略了Condition的示意图,因为Condition其实最终也是执行Node的。

 

文章转自公众号:三友的java日记

标签
已于2022-6-17 16:55:07修改
收藏
回复
举报
回复
    相关推荐