引擎API是与Flowable进行交互的最常见的方式。主要的出发点是ProcessEngine,可以按照配置部分所述的几种方式创建 。从
ProcessEngine中,您可以获取包含工作流程/ BPM方法的各种服务。ProcessEngine和服务对象是线程安全的,所以你可以保留对整个服务器的引用。
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
ManagementService managementService = processEngine.getManagementService();
IdentityService identityService = processEngine.getIdentityService();
HistoryService historyService = processEngine.getHistoryService();
FormService formService = processEngine.getFormService();
DynamicBpmnService dynamicBpmnService = processEngine.getDynamicBpmnService();
ProcessEngines.getDefaultProcessEngine()将在第一次被调用时初始化和构建流程引擎,并且之后总是返回相同的流程引擎。正确创建和关闭所有流程引擎可以使用ProcessEngines.init() 和完成ProcessEngines.destroy()。
该ProcessEngines类将扫描所有flowable.cfg.xml和flowable-context.xml文件。对于所有flowable.cfg.xml文件,流程引擎将以典型的Flowable方式构建:
ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine()。对于所有的flowable-context.xml文件,流程引擎都是以Spring的方式构建的:首先创建Spring应用程序上下文,然后从该应用程序上下文获取流程引擎。
所有服务都是无国籍的。这意味着您可以轻松地在群集中的多个节点上运行Flowable,每个节点都会转到同一个数据库,而不必担心哪台机器实际上执行了以前的调用。任何对任何服务的调用都是幂等的,而不管它在哪里执行。
该RepositoryService可能是可流动的发动机工作时所需要的第一个服务。这项服务提供运营管理和操纵deployments和process
definitions。这里没有详细讨论,流程定义是BPMN 2.0流程的Java对应。它是一个过程的每个步骤的结构和行为的表示。A deployment是
Flowable引擎内的包装单位。部署可以包含多个BPMN 2.0 XML文件和任何其他资源。包含在一个部署中的选择取决于开发人员。它可以从单个流程BPMN 2.0 XML文件到整个流程和相关资源包(例如,部署hr-processes可能包含与人力资源流程相关的一切)。该RepositoryService罐deploy这样的包。部署部署意味着将其上传到引擎,所有进程在存储到数据库之前都会被检查和解析。从这一点开始,系统已知部署,现在可以启动部署中包含的任何进程。
此外,这项服务允许您:
虽然RepositoryService主要是关于静态信息(数据不变,或者至少不是很多),但RuntimeService正好相反。它处理启动流程定义的新流程实例。如上所述,a process definition定义了一个过程中不同步骤的结构和行为。流程实例是这样一个流程定义的一个执行。对于每个流程定义,通常有许多实例同时运行。这RuntimeService也是用来检索和存储的服务process variables。这是特定于给定流程实例的数据,可以由流程中的各种构造使用(例如,排他网关通常使用流程变量来确定选择哪个路径来继续流程)。该Runtimeservice还允许您查询流程实例和执行情况。执行是’token’BPMN 2.0概念的表示。基本上,执行是指向当前流程实例的指针。最后,RuntimeService只要流程实例正在等待外部触发器,流程需要继续,就会使用它。一个流程实例可以有不同的wait states这种服务包含各种操作信号的情况下,外部触发被接收,可以继续流程实例。
系统的用户需要执行的任务是Flowable等BPM引擎的核心。任务周围的任务都被分组到TaskService中,如:
该IdentityService是非常简单的。它支持组和用户的管理(创建,更新,删除,查询…)。了解Flowable实际上不会在运行时对用户进行任何检查,这一点很重要。例如,可以将任务分配给任何用户,但是引擎不验证该用户是否被系统知晓。这是因为Flowable引擎也可以与LDAP,Active Directory等服务结合使用。
该FormService是一个可选的服务。这意味着Flowable在没有任何功能的情况下可以很快乐地使用。该服务引入了开始表格和任务表格的概念。一开始的形式是流程实例启动前显示给用户的一种形式,而任务的形式是当一个用户要填写一份表格的形式显示出来。Flowable允许在BPMN 2.0流程定义中指定这些表单。该服务以简单的方式公开这些数据。但同样,这是可选的,因为表单不需要嵌入到流程定义中。
该HistoryService暴露了可流动的引擎收集的所有历史数据。当执行进程时,引擎可以保存大量数据(这是可配置的),比如流程实例启动时间,谁做了哪些任务,完成任务需要多长时间,每个流程实例中遵循哪条路径,等等。该服务主要公开查询功能来访问这些数据。
该ManagementService编码使用可流动的自定义应用程序时,通常是没有必要的。它允许检索有关数据库表和表元数据的信息。此外,它还暴露了查询功能和作业管理操作。作业在Flowable中用于各种事情,如定时器,异步延期,延迟挂起/激活等等。稍后,将更详细地讨论这些主题。
DynamicBpmnService可以用来改变流程定义的一部分,而无需重新部署。例如,可以在流程定义中更改用户任务的受理人定义,或者更改服务任务的类名称。
有关服务操作和引擎API的更多详细信息,请参阅javadoc。
Flowable中的基本异常是org.flowable.engine.FlowableException一个未经检查的异常。此异常可以在任何时候通过API被抛出,但预计在具体方法所发生的都记录例外的javadoc。例如,摘录自TaskService:
/**
* Called when the task is successfully executed.
* @param taskId the id of the task to complete, cannot be null.
* @throws FlowableObjectNotFoundException when no task exists with the given id.
*/
void complete(String taskId);
在上面的例子中,当没有任何任务存在的时候,会抛出一个异常。另外,由于javadoc 明确指出taskId不能为null,所以FlowableIllegalArgumentException在null传递时会抛出。
尽管我们想要避免一个很大的异常层次结构,但在特定情况下会抛出以下子类。在过程执行或API调用期间发生的所有其他错误(不适合下面可能的例外情况)都会以常规方式抛出FlowableExceptions。
查询引擎中的数据有两种方式:查询API和本机查询。查询API允许您使用流畅的API编程完全类型安全的查询。您可以为查询添加各种条件(所有这些条件都作为逻辑“与”一起应用),而且恰恰是一种排序。以下代码显示了一个示例:
List<Task> tasks = taskService.createTaskQuery()
.taskAssignee("kermit")
.processVariableValueEquals("orderId", "0815")
.orderByDueDate().asc()
.list();
有时您需要更强大的查询,例如,使用OR运算符的查询或使用查询API无法表达的约束。对于这些情况,我们有本地查询,它允许您编写自己的SQL查询。返回类型由您使用的Query对象定义,数据映射到正确的对象(Task,ProcessInstance,Execution,…)。由于查询将在数据库中被触发,因此必须使用数据库中定义的表名和列名称; 这需要一些有关内部数据结构的知识,建议小心使用本机查询。表名可以通过API检索,以保持依赖性尽可能小。
List<Task> tasks = taskService.createNativeTaskQuery()
.sql("SELECT count(*) FROM " + managementService.getTableName(Task.class) +
" T WHERE T.NAME_ = #{taskName}")
.parameter("taskName", "gonzoTask")
.list();
long count = taskService.createNativeTaskQuery()
.sql("SELECT count(*) FROM " + managementService.getTableName(Task.class) + " T1, " +
managementService.getTableName(VariableInstanceEntity.class) + " V1 WHERE V1.TASK_ID_ = T1.ID_")
.count();
上面文章来自盘古BPM研究院:http://vue.pangubpm.com/
文章翻译提交:https://github.com/qiudaoke/flowable-userguide
了解更多文章可以关注微信公众号: