使用指南 

入门实践

       在源码的test目录下有quickstart测试用例(easyflow\easyflow-flow\src\test\java\com\jd\easyflow\flow\quickstart\QuickStartTest.java),可直接运行或调试以了解使用方式和运行原理。

具体实践步骤如下:

1、代码中引入easyflow-flow jar包

以maven为例:

<dependency>
        <groupId>com.jd.easyflow</groupId>
        <artifactId>easyflow-flow</artifactId>
        <version>{替换为最新版本}</version>
</dependency>

2、编写流程定义文件

以node001->node002→node003的执行顺序为例:

{"id": "quickstart_001", "name": "Quick Start 001",
"nodes": [
  {"id": "node001","name": "Node001","action": {"createExp": "new com.jd.easyflow.flow.quickstart.QuickStart001Node01Action()"},"start": true,"post": {"to": "node002"}},
  {"id": "node002","name": "Node002","action": {"createExp": "new com.jd.easyflow.flow.quickstart.QuickStart002Node01Action()"},"post": {"to": "node003"}},
  {"id": "node003","name": "Node003","action": {"createExp": "new com.jd.easyflow.flow.quickstart.QuickStart003Node01Action()"}}
]
}

其中QuickStart001Node01Action等为java节点动作类

3、编写应用启动时加载流程引擎的代码

  

FlowEngineImpl flowEngine = new FlowEngineImpl();
flowEngine.setFlowPath("classpath:flow/quickstart/quickstart_001.json");
flowEngine.init();

Spring环境可直接定义FlowEngineImpl bean.

 4、编写具体流程调用执行的代码

FlowParam param = new FlowParam("quickstart_001");
FlowResult result = flowEngine.execute(param);

完整测试用例的执行结果打印如下:

[main            ] INFO  FlowEngineImpl          - Start parsing definition files:easyflow-flow/target/test-classes/flow/quickstart/quickstart_001.json
[main            ] INFO  FlowEngineImpl          - SART EXECUTE FLOW, flowId:quickstart_001 nodeIds:null
[main            ] INFO  BaseFlowRunner          - EXECUTE NODE:node001
[main            ] INFO  QuickStart001Node01Action  - Execute Node 001
[main            ] INFO  BaseFlowRunner          - NEXT NODES:node002
[main            ] INFO  BaseFlowRunner          - EXECUTE NODE:node002
[main            ] INFO  QuickStart002Node01Action  - Execute Node 002
[main            ] INFO  BaseFlowRunner          - NEXT NODES:node003
[main            ] INFO  BaseFlowRunner          - EXECUTE NODE:node003
[main            ] INFO  QuickStart003Node01Action  - Execute Node 003
[main            ] INFO  BaseFlowRunner          - NEXT NODES:
[main            ] INFO  QuickStartTest          - Execute finish, current node is:node003

流程定义元素和参数说明

整体配置项说明

一级元素

二级元素

三级元素

名称

说明

id

流程ID

全局唯一

name

流程名称

nodes

节点列表

id

节点ID

流程定义内唯一

name

节点名称

action

节点动作

exp

执行的 spel 表达式

createExp

节点动作的创建表达式

返回结果必须为 NodeAction 接口的实现

flow

子流程定义

子流程定义

flowId

子流程 ID

子流程 ID

startNodeId

子流程开始节点 ID

子流程开始节点 ID,格式为字符串或字符串数组

post

节点后置处理器

主要控制后继节点逻辑,目前支持: 固定后继节点 条件后继节点 动态计算 具体配置方式见后

listeners

监听器列表

createExp

监听器创建表达式

filters

流程过滤器列表

nodeFilters

节点过滤器列表

nodePreHandlerFilters

节点前置处理过滤器

createExp

过滤器创建表达式

nodeActionFilters

节点动作过滤器列表

createExp

过滤器创建表达式

NodePostHandlerFilters

节点后置处理过滤器

createExp

过滤器创建表达式

runner

流程执行器

默认为串行执行器,可配置为多线程执行器。

createExp

流程执行器表达式

properties

流程属性

flow.recordHistory

是否记录流程执行的节点历史

默认为是。如果一次流程运行执行非常多次(千万或亿或死循环,一般不会发生),需要设为 false

post配置说明

post有如下几种配置规范:

一、固定值

1、{"to":XXX},到to节点

二、条件类

2、{"when":XXX, "to":XXX},当when条件满足时到to节点

3、{"conditions":[{"when":XXX, "to":XXX},{"when":XXX, "to":XXX}]},多个条件

when为el表达式

条件类可配置参数conditionType,取值有exclusive/inclusive,默认为exclusive,只要一个分支条件判断成功,则判断逻辑终止;

条件类可配置参数defaultTo,当条件没有满足的时的默认分支

三、创建表达式

4、{"createExp":XXX},流程解析时执行此表达式,计算值为一个NodePostHandler的实现类

四、表达式

5、{"exp":XXX},流程运行时执行此表达式,计算值为to配置(见下)可接受的类型

to的配置说明

如果为字符串,如果以开头,则代表索引值,取值有first, last,previous, $next,否则代表固定的节点ID
如果为整数,则代表节点索引值
如果为List,则代表字符串或整数值列表
如果为Map,则可以配置"exp":"XXX",根据EL值动态计算后继节点,具体的值类型为字符串、整数或List

配置示例见test目录相关用例。

SPEL表达式固定变量

流程执行过程中变量

名称

类型

说明

context

FlowContext

流程上下文

param

FlowParam

流程参数

bizParam

依赖业务传入

FlowParam中的param

paramData

Map

对应FlowParam中的dataMap

result

FlowResult

流程结果

bizResult

依赖业务传入

FlowResult中的result

nodeContext

NodeContext

节点上下文

actionResult

依赖具体接口实现

节点动作的执行结果

其他

过滤器和监听器使用说明

过滤器和监听器均为横向控制的方式,区别在于监听器侧重监听,对流程的控制有限,过滤器侧重过滤,可以捕获异常或流程处理等。

流程异常处理

默认情况下,流程引擎不捕获和封装异常,业务逻辑中抛出的异常直接抛出;对于多线程执行场景下,如果多个节点同时有异常,会任选其一抛出,同时可以从流程上下文中获取所有异常。

对于节点异常可以通过节点过滤器统一捕获做业务逻辑处理,或者可通过流程过滤器统一捕获做业务逻辑处理。