Easy Work 是一个用于 Java 的工作流引擎。它通过简洁的API和构建模块,帮助你轻松创建和运行可组合的工作流。
在Easy Work中,最核心的两个概念是工作单元(Work)和工作流(WorkFlow)。一个工作单元通过实现 Work 接口来表示,而工作流则由 WorkFlow 接口来定义。该引擎已经为你提供了 WorkFlow 接口的6种核心实现,覆盖了绝大多数业务流程编排的场景。

这些就是你使用Easy Work构建流程时需要掌握的全部基础流程类型。你不必去学习复杂的流程图符号或晦涩的概念,只需要理解这几个直观的API即可快速上手。
如何使用?
首先,我们来创建一个具体的工作单元(Work):
public class PrintMessageWork implements Work{
private final String message;
public PrintMessageWork(String message){
this.message = message;
}
@Override
public String execute(WorkContext workContext){
System.out.println(message);
return message;
}
}
这个 PrintMessageWork 非常简单,就是将指定的消息打印到标准输出。现在,假设我们需要编排一个稍微复杂点的业务流程,具体要求如下:
- 将任务
a 重复执行三次。
- 接着,按顺序依次执行任务
b、c、d。
- 然后,并行执行任务
e 和 f。
- 根据上一步并行执行的结果进行判断:如果成功,则执行
g,否则执行 h。
- 最后,执行收尾任务
z。
这个流程用图形表示会更直观:

是不是听起来有些抽象?让我们用 Easy Work 的术语来分解一下:
flow1 是一个 RepeatFlow,用于重复打印 a 三次。
flow2 是一个 SequentialFlow,用于顺序打印 b、c、d。
flow3 是一个 ParallelFlow,用于并行打印 e 和 f。
flow4 是一个 ConditionalFlow,它会先执行 flow3,然后根据其执行结果(状态为 COMPLETED 表示成功)来决定是执行 g 还是 h。
flow5 是一个顶层的 SequentialFlow,它保证了 flow1、flow2、flow4 和 z 会按顺序依次执行。
用代码来实现上述流程,你会发现它的表达非常直接:
PrintMessageWork a = new PrintMessageWork(“a”);
PrintMessageWork b = new PrintMessageWork(“b”);
PrintMessageWork c = new PrintMessageWork(“c”);
PrintMessageWork d = new PrintMessageWork(“d”);
PrintMessageWork e = new PrintMessageWork(“e”);
PrintMessageWork f = new PrintMessageWork(“f”);
PrintMessageWork g = new PrintMessageWork(“g”);
PrintMessageWork h = new PrintMessageWork(“h”);
PrintMessageWork z = new PrintMessageWork(“z”);
WorkFlow flow = aNewSequentialFlow(
aNewRepeatFlow(a).times(3),
aNewSequentialFlow(b,c,d),
aNewConditionalFlow(
aNewParallelFlow(e,f).withAutoShutDown(true)
).when(
WorkReportPredicate.COMPLETED,
g,
h
),
z
);
aNewWorkFlowEngine().run(flow, new WorkContext());
通过这样流畅的链式调用,一个复杂的业务逻辑就被清晰地定义出来了,这正是设计良好的 流程编排 工具的威力所在。
暂停工作流(断点功能)
从 v1.0.5 版本开始,Easy Work 支持工作流断点功能。你可以在流程的任意位置设置断点,暂停执行以进行一些外部操作(例如等待人工审批、调用外部接口等),之后再恢复执行。
例如,我们可以在上面的流程中,在 c 这个工作单元处设置一个断点:

对应的代码实现如下:
SequentialFlow flow = aNewSequentialFlow(
aNewRepeatFlow(a).times(3),
aNewSequentialFlow(b,aNamePointWork(c).point(“C_BREAK_POINT”),d),
aNewConditionalFlow(
aNewParallelFlow(e,f).withAutoShutDown(true)
).when(
WorkReportPredicate.COMPLETED,
g,
h
),
z
);
// 执行到该断点并暂停
flow.execute(“C_BREAK_POINT”);
System.out.println(“execute to the break point `C_BREAK_POINT`”);
// 从断点处继续执行,直到完成
flow.execute();
通过JSON构建工作流
从 V1.0.8 开始,Easy Work 提供了基于 JSON 定义工作流的能力。这为动态配置、流程可视化编辑以及持久化存储提供了极大的便利。以上述图示中的复杂流程为例,我们可以用如下的 JSON 结构(保存为 example.json)来描述它:
{
“type”: “sequential”,
“works”: [{
“type”: “repeat”,
“times”: 3,
“work”: {
“type”: “work.PrintMessageWork”,
“message”: “a”
}
},{
“type”: “sequential”,
“works”: [{
“type”: “work.PrintMessageWork”,
“message”: “b”
},{
“type”: “work.PrintMessageWork”,
“message”: “c”
},{
“type”: “work.PrintMessageWork”,
“message”: “d”
}]
},{
“type”: “conditional”,
“decide”: {
“type”: “parallel”,
“autoShutdown”: true,
“works”: [{
“type”: “work.PrintMessageWork”,
“message”: “e”
},{
“type”: “work.PrintMessageWork”,
“message”: “f”
}]
},
“predicate”: {
“left” : “$status”,
“operator”: “eq”,
“right”: “COMPLETED”
},
“trueWork”: {
“type”: “work.PrintMessageWork”,
“message”: “g”
},
“falseWork”: {
“type”: “work.PrintMessageWork”,
“message”: “h”
}
}],
“then”: {
“type”: “work.PrintMessageWork”,
“message”: “z”
}
}
然后,在 Java 代码中,你可以轻松地将这个 JSON 反序列化为工作流对象并执行:
String json = ResourceReader.readJSON(“json/example.json”);
SequentialFlow sequentialFlow = (SequentialFlow) deserialize(json);
sequentialFlow.execute(new WorkContext());
上面的示例虽然简单,但已经完整展示了 Easy Work 的核心能力:通过极简的 API 或声明式的 JSON 来编排复杂业务流程。如果你对更多高级用法和测试用例感兴趣,可以查阅项目中的 test/java 目录。
这是一个由社区驱动的 开源实战 项目,你可以在 Gitee 上找到它的全部源码和最新动态:
https://gitee.com/ifrog/easy-work
希望这个轻量级、易上手的 Java 流程引擎能为你解决业务编排的难题。如果在云栈社区有更多关于系统设计或框架选型的讨论,欢迎一起交流探讨。
