flow - 流驱动器的组搭和定制
流驱动器(FlowDriver)的相关接口,主要有三个:
接口 | 描述 |
---|---|
FlowDriver | 流驱动接口定义 |
AbstractFlowDriver | 虚拟流驱动器,实现基本能力,并抽象出:脚本运行接口(Evaluation)和组件容器接口(Container)。一般做为基类使用 |
SimpleFlowDriver | 简单流驱动器。以 AbstractFlowDriver 为基础,提供 Evaluation 和 Container 组搭支持。 |
StatefulFlowDriver | 有状态流驱动接口定义。以 FlowDriver 为基础 |
StatefulSimpleFlowDriver | 有状态的简单流驱动器。以 SimpleFlowDriver 为基础定制。 |
有状态是指:活动节点会有等待、完成、退回、重新开始等状态(或指令)。应用场景不同。
1、SimpleFlowDriver 的默认状态
当使用默认构造时,默认会使用 LiquorEvaluation 脚本评估器和 SolonContainer 组件容器。
SimpleFlowDriver flowDriver = new SimpleFlowDriver();
流引擎,默认的驱动器就是这个状态。
2、SimpleFlowDriver 的简单组搭
可选的组搭组件(可自己定制)
组件 | 类型 | 描述 |
---|---|---|
MapContainer | 组件容器 | 基于 Map 实现的组件容器(适合无容器环境) |
SolonContainer | 组件容器 | 对接 solon 的组件容器 |
LiquorEvaluation | 脚本评估器 | 基于 liquor 实现,支持完整 java 语法的条件与脚本 |
AviatorEvaluation | 脚本评估器 | 基于 aviator 实现,支持完整 aviator 语法的条件与脚本 |
BeetlEvaluation | 脚本评估器 | 基于 beetl 实现,支持完整 beetl 语法的条件与脚本 |
MagicEvaluation | 脚本评估器 | 基于 magic 实现,支持完整 magic 语法的条件与脚本 |
- AviatorEvaluation,需要引入包:
org.noear:solon-flow-eval-aviator
- BeetlEvaluation,需要引入包:
org.noear:solon-flow-eval-beetl
- MagicEvaluation,需要引入包:
org.noear:solon-flow-eval-magic
简单组搭示例:
//构建组件容器
MapContainer container = new MapContainer();
container.putComponent("DemoCom", (ctx, node)->{
System.out.println(node.getId());
});
//构建驱动
SimpleFlowDriver flowDriver = new SimpleFlowDriver(container);
//构建引擎
FlowEngine engine = FlowEngine.newInstance();
engine.register(flowDriver);
//-----
//动态构建链,并执行
Chain chain = new Chain("c1");
chain.addNode(NodeDecl.activityOf("n1").task("@DemoCom"));
engine.eval(chain.getNode("n1"), new FlowContext());
3、驱动器定制参考
驱动器的定制,可以基于 SimpleFlowDriver 进行重写与扩展(比较重),也可以定制脚本执行器和组件容器进行组搭(比较轻)。
定制脚本执行器参考 AviatorEvaluation:
public class AviatorEvaluation implements Evaluation {
@Override
public boolean runTest(FlowContext context, String code) {
return (Boolean) AviatorEvaluator.execute(code, context.model());
}
@Override
public void runTask(FlowContext context, String code) {
AviatorEvaluator.execute(code, context.model());
}
}
//应用
//SimpleFlowDriver flowDriver = new SimpleFlowDriver(new AviatorEvaluation());
定制组件容器参考 SpringContainer(比如把它应用到 Spring 环境):
@Component
public class SpringContainer implements Container, ApplicationContextAware {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) {
this.context = context;
}
@Override
public Object getComponent(String componentName) {
return context.getBean(componentName);
}
}
//应用
//@Configuration
//public class FlowEngineConfig {
// @Bean
// public FlowEngine flowEngine(SpringContainer container) {
// FlowEngine flowEngine = FlowEngine.newInstance();
//
// flowEngine.register(new SimpleFlowDriver(container));
// flowEngine.load("classpath:flow/*.yml")
//
// return flowEngine;
// }
//}
定制流驱动器参考 StatefulSimpleFlowDriver(框架已内置):
public class StatefulSimpleFlowDriver extends SimpleFlowDriver implements FlowDriver, StatefulFlowDriver {
private final StateRepository stateRepository;
private final StateController stateController;
public StatefulSimpleFlowDriver(StateRepository stateRepository, StateController stateController, Evaluation evaluation, Container container) {
super(evaluation, container);
this.stateRepository = (stateRepository == null ? new InMemoryStateRepository() : stateRepository);
this.stateController = (stateController == null ? new BlockStateController() : stateController);
}
/**
* 获取状态仓库
*/
@Override
public StateRepository getStateRepository() {
return stateRepository;
}
/**
* 获取状态控制器
*/
@Override
public StateController getStateController() {
return stateController;
}
/**
* 提交处理任务
*
* @param context 流上下文
* @param task 任务
*/
@Override
public void postHandleTask(FlowContext context, Task task) throws Throwable {
super.handleTask(context, task);
}
/**
* 处理任务
*
* @param context 流上下文
* @param task 任务
*/
@Override
public void handleTask(FlowContext context, Task task) throws Throwable {
String instanceId = context.getInstanceId();
if (Utils.isNotEmpty(instanceId)) {
//有实例id,作有状态处理
if (stateController.isAutoForward(context, task.getNode())) {
//自动前进
StateType state = getStateRepository().getState(context, task.getNode());
if (state == StateType.UNKNOWN || state == StateType.WAITING) {
//添加状态
stateRepository.putState(context, task.getNode(), StateType.COMPLETED);
//发送提交变更事件
stateRepository.onPostActivityState(context, task.getNode(), StateType.COMPLETED);
//确保任务只被执行一次
postHandleTask(context, task);
} else if (state == StateType.TERMINATED) {
//终止
context.stop();
}
} else {
//控制前进
StateType state = getStateRepository().getState(context, task.getNode());
List<StatefulNode> nodeList = context.computeIfAbsent(StatefulNode.KEY_ACTIVITY_LIST, k -> new ArrayList<>());
boolean nodeListGet = context.getOrDefault(StatefulNode.KEY_ACTIVITY_LIST_GET, false);
if (state == StateType.UNKNOWN || state == StateType.WAITING) {
//检查是否为当前用户的任务
if (stateController.isOperatable(context, task.getNode())) {
//记录当前流程节点(用于展示)
StatefulNode statefulNode = new StatefulNode(task.getNode(), StateType.WAITING);
context.put(StatefulNode.KEY_ACTIVITY_NODE, statefulNode);
nodeList.add(statefulNode);
if (nodeListGet) {
context.interrupt();
} else {
context.stop();
}
} else {
//阻断当前分支(等待别的用户办理)
StatefulNode statefulNode = new StatefulNode(task.getNode(), StateType.UNKNOWN);
context.put(StatefulNode.KEY_ACTIVITY_NODE, statefulNode);
nodeList.add(statefulNode);
context.interrupt();
}
} else if (state == StateType.TERMINATED) {
//终止
StatefulNode statefulNode = new StatefulNode(task.getNode(), StateType.TERMINATED);
context.put(StatefulNode.KEY_ACTIVITY_NODE, statefulNode);
nodeList.add(statefulNode);
if (nodeListGet) {
context.interrupt();
} else {
context.stop();
}
}
}
} else {
//没有实例id,作无状态处理 //直接提交处理任务
postHandleTask(context, task);
}
}
}