基于 liteflow-2.11.4.2版本,同时通过编码的方式进行配置 liteflow规则
官方说明
LiteFlow就是为解耦复杂逻辑而生,如果你要对复杂业务逻辑进行新写或者重构,用LiteFlow最合适不过。它是一个轻量,快速的组件式流程引擎框架,组件编排,帮助解耦业务代码,让每一个业务片段都是一个组件,并支持热加载规则配置,实现即时修改。
使用LiteFlow,你需要去把复杂的业务逻辑按代码片段拆分成一个个小组件,并定义一个规则流程配置。这样,所有的组件,就能按照你的规则配置去进行复杂的流转。
依赖
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-core</artifactId>
<version>2.11.4.2</version>
</dependency>
配置
public static void main(String[] args) {
// 1. 定义liteflow node的信息
FlowBus.addManagedNode("a", new ACmp());
FlowBus.addManagedNode("b", new BCmp());
FlowBus.addManagedNode("c", new CCmp());
FlowBus.addManagedNode("d", new DCmp());
// 2. 定义liteflow chain信息
LiteFlowChainELBuilder.createChain()
.setChainId("chainA") // chain 名称
.setEL("THEN(a,WHEN(b,c),d)") // chain的表达式,then表达式是串行的,when 是异步执行的
.build(); // 创建chain
// 3. 创建FlowExecutor 执行指定的chain
FlowExecutorHolder.loadInstance(new LiteflowConfig())
// 配置自定义的上下文对象ContextBean,在NodeComponent中可以通过getSlot().getContextBean获取
// param参数是配置为请求的上下文,也是属于slot中的一部分数据
// slot 数据槽作为每个执行链的共享数据,各执行链之间的数据是隔离的
// 为什么设置一个slot对象出来呢?
// 个人理解是为了统一管理,因为要考虑串行、并行的情况,如果将一个对象在各个线程中传递,会变得很复杂
// 将slot统一管理,只需要传递当前链使用slotIndex 即可
.execute2Resp("chainA", null, new ContextBean());
}
定义node信息
FlowBus.addManagedNode("a", new ACmp());
FlowBus.addManagedNode("b", new BCmp());
FlowBus.addManagedNode("c", new ACmp());
FlowBus.addManagedNode("d", new BCmp());
node是 liteflow中执行业务逻辑的节点信息,每个node是一个组件,负责处理其中的一个业务逻辑,是组件执行链(chain)的子元素。
定义chain
// 2. 定义liteflow chain信息
LiteFlowChainELBuilder.createChain()
.setChainId("chainA") // chain 名称
.setEL("THEN(a,WHEN(b,c),d)") // chain的表达式,then表达式是串行的,when 是异步执行的
.build(); // 创建chain
liteflow 真正运行的就是具体的链,链将每个节点进行组合,作为其真正的业务控制逻辑来执行。
其中:
chianId 配置该条链的编号,后续可以通过该编号进行执行
EL 配置链的执行表达式
上述的执行流程图如下:
其中 THEN表达式是串行的,WHEN表达式是并行处理的
执行链
// 3. 创建FlowExecutor 执行指定的chain
FlowExecutorHolder.loadInstance(new LiteflowConfig())
// 配置自定义的上下文对象ContextBean,在NodeComponent中可以通过getSlot().getContextBean获取
// param参数是配置为请求的上下文,也是属于slot中的一部分数据
// slot 数据槽作为每个执行链的共享数据,各执行链之间的数据是隔离的
// 为什么设置一个slot对象出来呢?
// 个人理解是为了统一管理,因为要考虑串行、并行的情况,如果将一个对象在各个线程中传递,会变得很复杂
// 将slot统一管理,只需要传递当前链使用slotIndex 即可
.execute2Resp("chainA", null, new ContextBean());
在定义完节点和链的信息后,就可以开始执行具体的链来完成业务逻辑,通过 FlowExecutorHolder.loadInstance(new LiteflowConfig())来获取 FlowExecutor对象(该对象建议是单例,因为创建比较重)。
数据槽
因为liteflow中的chain是由不同的node组件组成的,那在不同的组件中如何传递数据呢?
liteflow 会在执行每个chain时,分配一个唯一的数据槽(slot)给当前的请求,每个流程的数据槽都是完全隔离的,每个组件都是不传递参数,最终都是以这个数据槽来数据交互的。
为什么设计一个slot对象出来呢?
个人理解是为了统一管理,因为要考虑串行、并行的情况,如果将一个对象在各个线程中传递,会变得很复杂
将slot统一管理,只需要传递当前链使用slotIndex 即可。
slot也提供了以下方法来处理不同场景的数据获取:
// 获取某个节点的输入数据
public <T> T getInput(String nodeId)
// 获取某个节点的输出数据
public <T> T getOutput(String nodeId)
// 设置某个节点的输入数据
public <T> void setInput(String nodeId, T t)
// 设置某个节点的输出数据
public <T> void setOutput(String nodeId, T t)
// 获取流程的初始参数数据,由execute2Response中的param参数传递
public <T> T getRequestData()
// 设置初始参数
public <T> void setRequestData(T t)
// 获取属于chain的数据
public <T> T getChainReqData(String chainId)
// 设置属于chain的数据
public synchronized <T> void setChainReqData(String chainId, T t)
本文暂时没有评论,来添加一个吧(●'◡'●)