Fluent Builder API官方文档位置:Fluent Builder API | docs.camunda.org
首先提前说明一点:这个API可以正确生成流程定义,流程定义也可以使用,但是如果想要生成清晰明了,不需要修改就可以使用的可以观看的流程定义图的话,是不一定成功的,举一个简单的例子。
@Test
public void t5(){
BpmnModelInstance modelInstance = Bpmn.createExecutableProcess()
.startEvent()
.userTask()
.id("question")
.exclusiveGateway("bk")
.name("Everything fine?")
.condition("no", "#{!fine}")
.userTask()
.connectTo("question")
.moveToNode("bk")
.condition("yes", "#{fine}")
.userTask()
.endEvent()
.done();
File outputFile = new File("src/main/resources/processes/test.bpmn20.xml");
Bpmn.writeModelToFile(outputFile, modelInstance);
}
运行后,使用camunda-modeler打开这个test.bpmn20.xml,你就会发现:
它有线条被压在节点的下面,而且顺序流还有重合,这就导致不看代码你无法第一时间知道它是怎么走的,只有当你把它的代码看过以后,才有可能能读懂,但是如果代码再长一些呢?短时间也无法看懂。那么你可能会在camunda-modeler中把它拉一拉换换位置,把顺序流也调整一下,可能可以调整出来一个不错的展示效果。
但是还是一样的问题,如果这个节点更多一些呢?你可能就需要消耗大量的时间去调整它。
当然,这个问题之后会提到,虽然不可能完全解决,但是有办法进行一定程度的优化。下面开始正式讲解Fluent Builder API:
Fluent Builder API它并不是一个完美的API,不过它可以让我们进行一些,创建简单的BPMN流程。
Bpmn.createProcess()
.startEvent()
.userTask()
.endEvent()
.done();
这样就可以创建一个只有开始事件、一个用户任务、一个结束事件的流程,但是这样的流程部署后无法启动流程实例,部署的方法如下:
BpmnModelInstance done = Bpmn.createProcess()
.startEvent()
.userTask()
.endEvent()
.done();
repositoryService.createDeployment()
.addModelInstance("done"+".bpmn20.xml",done)
.deploy();
原因是这样的流程不是ExecutableProcess,所以在act_re_procdef表中是没有它的,而流程实例开启,是根据这个表里的流程定义选取最新版本进行开启的,所以这里有两种方法,一种是在创建的时候就指定为ExecutableProcess:
BpmnModelInstance done = Bpmn.createExecutableProcess()
.startEvent()
.userTask()
.endEvent()
.done();
另外一种就是在后续再指定,如:
BpmnModelInstance done = Bpmn.createProcess()
.startEvent()
.userTask()
.endEvent()
.done();
Process process = done.getModelElementsByType(Process.class).iterator().next();
process.setExecutable(true);
只有ExecutableProcess部署以后的流程定义,才可以正常的开启流程实例。
最简单的流程定义就这样定义好了,那么如果想要复杂一点的呢?比如我要增添网关进行条件选择等。(FLUENT BuilderAPI支持的基本元素可以在官方文档中找到)
Bpmn.createExecutableProcess()
.name("test")
.id("test")
.startEvent("start")
.userTask("people")
.exclusiveGateway("question")
.name("能成功吗?")
.condition("no", "#{!answer}")
.userTask("something")
.connectTo("people")
.moveToNode("question")
.condition("yes", "#{answer}")
.userTask()
.endEvent()
.done();
如上述的代码与图片,id可以单独指定,也可以在创建元素的时候同时指定。其中exclusiveGateway是排他网关,condition就是排他网关的条件。condition的条件分别是"#{!answer}"和"#{answer}",也就是流程实例进行到这里需要传入一个参数answer。
moveToNode的意思是返回到某个节点,指定的是id,此处是因为上一个condition后续都安排好了,所以重新回到排他网关进行第二个condition的安排。
connectTo的意思是,连接到某个节点上,指定的是id,这里是“就是不成功就去做些什么事,然后重新面临问题”,也就是一个回退操作(回退操作还有其他的方式,后续教程会讲到)。
如此,我们就完成了一个简单的拥有排他网关的流程定义,当然,它的流程图会出现我们最前面说过的问题。
更多更复杂的操作,实际上Fluent Builder API并不能完成,经过我的实际操作,官方文档给出的扩展进程并不能实现,也就是说,完全按照官方提供的代码进行操作却无法达到实际想要得到的效果:
于是对于扩展和修改流程定义来说,我更倾向于另一种编写流程定义的方式,虽然那种编写流程定义的方式不会生成流程图,但是我们可以自定义生成流程图,从而完成定制化的流程图生成。这另一种的方式会在后续教程中讲到: