中文文档
https://tkjohn.github.io/flowable-userguide/
flowable ui
https://github.com/flowable/flowable-engine/releases/download/flowable-6.7.0/flowable-6.7.0.zip
pom
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-engine</artifactId>
<version>6.6.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
生成表
public class flowableTest {
@Test
public void flow(){
ProcessEngineConfiguration cfg=new StandaloneProcessEngineConfiguration();
cfg.setJdbcDriver("com.mysql.cj.jdbc.Driver");
cfg.setJdbcUrl("jdbc:mysql://localhost:3306/flowable?serverTimezone=Asia/Shanghai&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false");
cfg.setJdbcUsername("root");
cfg.setJdbcPassword("root");
//如果数据库表不存在就新建
cfg.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
cfg.buildProcessEngine();
}
}
数据库
1、Flowable的所有数据库表都以ACT_开头。第二部分是说明表用途的两字符标示符。服务API的命名也大略符合这个规则。
2、ACT_RE_: 'RE’代表repository。带有这个前缀的表包含“静态”信息,例如流程定义与流程资源(图片、规则等)。
3、ACT_RU_: 'RU’代表runtime。这些表存储运行时信息,例如流程实例(process instance)、用户任务(user task)、变量(variable)、作业(job)等。Flowable只在流程实例运行中保存运行时数据,并在流程实例结束时删除记录。这样保证运行时表小和快。
4、ACT_HI_: 'HI’代表history。这些表存储历史数据,例如已完成的流程实例、变量、任务等。
5、ACT_GE_: 通用数据。在多处使用。
1)通用数据表(2个)
- act_ge_bytearray:二进制数据表,如流程定义、流程模板、流程图的字节流文件;
- act_ge_property:属性数据表(不常用);
2)历史表(8个,HistoryService接口操作的表)
- act_hi_actinst:历史节点表,存放流程实例运转的各个节点信息(包含开始、结束等非任务节点);
- act_hi_attachment:历史附件表,存放历史节点上传的附件信息(不常用);
- act_hi_comment:历史意见表;
- act_hi_detail:历史详情表,存储节点运转的一些信息(不常用);
- act_hi_identitylink:历史流程人员表,存储流程各节点候选、办理人员信息,常用于查询某人或部门的已办任务;
- act_hi_procinst:历史流程实例表,存储流程实例历史数据(包含正在运行的流程实例);
- act_hi_taskinst:历史流程任务表,存储历史任务节点;
- act_hi_varinst:流程历史变量表,存储流程历史节点的变量信息;
3)用户相关表(4个,IdentityService接口操作的表)
- act_id_group:用户组信息表,对应节点选定候选组信息;
- act_id_info:用户扩展信息表,存储用户扩展信息;
- act_id_membership:用户与用户组关系表;
- act_id_user:用户信息表,对应节点选定办理人或候选人信息;
4)流程定义、流程模板相关表(3个,RepositoryService接口操作的表)
- act_re_deployment:部属信息表,存储流程定义、模板部署信息;
- act_re_procdef:流程定义信息表,存储流程定义相关描述信息,但其真正内容存储在act_ge_bytearray表中,以字节形式存储;
- act_re_model:流程模板信息表,存储流程模板相关描述信息,但其真正内容存储在act_ge_bytearray表中,以字节形式存储;
5)流程运行时表(6个,RuntimeService接口操作的表)
- act_ru_task:运行时流程任务节点表,存储运行中流程的任务节点信息,重要,常用于查询人员或部门的待办任务时使用;
- act_ru_event_subscr:监听信息表,不常用;
- act_ru_execution:运行时流程执行实例表,记录运行中流程运行的各个分支信息(当没有子流程时,其数据与act_ru_task表数据是一一对应的);
- act_ru_identitylink:运行时流程人员表,重要,常用于查询人员或部门的待办任务时使用;
- act_ru_job:运行时定时任务数据表,存储流程的定时任务信息;
- act_ru_variable:运行时流程变量数据表,存储运行中的流程各节点的变量信息;
流程引擎API与服务
1、RepositoryService很可能是使用Flowable引擎要用的第一个服务。这个服务提供了管理与控制部署(deployments)与流程定义(processdefinitions)的操作。
2、RuntimeService用于启动流程定义的新流程实例。
3、IdentityService很简单。它用于管理(创建,更新,删除,查询……)组与用户。
4、FormService是可选服务。也就是说Flowable没有它也能很好地运行,而不必牺牲任何功能。
5、HistoryService暴露Flowable引擎收集的所有历史数据。要提供查询历史数据的能力。
6、ManagementService通常在用Flowable编写用户应用时不需要使用。它可以读取数据库表与表原始数据的信息,也提供了对作业(job)的查询与管理操作。
7、DynamicBpmnService可用于修改流程定义中的部分内容,而不需要重新部署它。例如可以修改流程定义中一个用户任务的办理人设置,或者修改一个服务任务中的类名。
将下面的XML保存在src/main/resources文件夹下名为holiday-request.bpmn20.xml的文件中。
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
xmlns:flowable="http://flowable.org/bpmn"
typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.flowable.org/processdef">
<process id="holidayRequest" name="Holiday Request" isExecutable="true">
<startEvent id="startEvent"/>
<sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>
<userTask id="approveTask" name="Approve or reject request"/>
<sequenceFlow sourceRef="approveTask" targetRef="decision"/>
<exclusiveGateway id="decision"/>
<sequenceFlow sourceRef="decision" targetRef="externalSystemCall">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[
${approved}
]]>
</conditionExpression>
</sequenceFlow>
<sequenceFlow sourceRef="decision" targetRef="sendRejectionMail">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[
${!approved}
]]>
</conditionExpression>
</sequenceFlow>
<serviceTask id="externalSystemCall" name="Enter holidays in external system"
flowable:class="org.flowable.CallExternalSystemDelegate"/>
<sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/>
<userTask id="holidayApprovedTask" name="Holiday approved"/>
<sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>
<serviceTask id="sendRejectionMail" name="Send out rejection email"
flowable:class="org.flowable.SendRejectionMail"/>
<sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/>
<endEvent id="approveEnd"/>
<endEvent id="rejectEnd"/>
</process>
</definitions>
流程部署
ProcessEngine processEngine = cfg.buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment().addClasspathResource("holiday-request.bpmn20.xml").deploy();
查询流程定义信息
ProcessEngine processEngine = cfg.buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
/**
* Deployment deployment
* deploymentId 设置流程id(deployment.getId())
* singleResult 返回单个
*/
ProcessDefinition processDefinition = processDefinitionQuery.deploymentId(deployment.getId()).singleResult();
删除流程
ProcessEngine processEngine = cfg.buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
/**
* deleteDeployment
* Deployment deployment
* 第一参数是流程id(deployment.getId()) 如果流程启动将不允许删除
* 第二参数数级联删除 如果流程启动了也可以删除 相关的任务也会删除
*/
repositoryService.deleteDeployment(deployment.getId());
ProcessDefinitionQuery processDefinitionQuery =
repositoryService.createProcessDefinitionQuery();
启动流程
ProcessEngine processEngine = cfg.buildProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
//表单信息 例如请假人的信息
Map<String,Object> map=new HashMap<>();
//<process id="holidayRequest" name="Holiday Request" isExecutable="true">
runtimeService.startProcessInstanceByKey("holidayRequest",map);
查询当前登录用户任务
ProcessEngine processEngine = cfg.buildProcessEngine();
//查询任务
TaskService taskService = processEngine.getTaskService();
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("xml中流程的id")
.taskAssignee("")//任务处理人
.list();
结束任务
ProcessEngine processEngine = cfg.buildProcessEngine();
//查询任务
TaskService taskService = processEngine.getTaskService();
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("xml中流程的id")
.taskAssignee("")//任务处理人
.list();
//创建流程变量
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("approved", approved);
for (Task task: taskList ) {
//结束
taskService.complete(task.getId(), variables);
}
获取已完成的流程任务历史记录(一般用于统计处理耗时)
ProcessEngine processEngine = cfg.buildProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
List<HistoricActivityInstance> activities =
historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstance.getId())
.finished()
.orderByHistoricActivityInstanceEndTime().asc()
.list();
for (HistoricActivityInstance activity : activities) {
System.out.println(activity.getActivityId() + " took "
+ activity.getDurationInMillis() + " milliseconds");
}
服务任务(service task)
<serviceTask id="externalSystemCall" name="Enter holidays in external system"
flowable:class="org.flowable.CallExternalSystemDelegate"/>
public class CallExternalSystemDelegate implements JavaDelegate {
public void execute(DelegateExecution execution) {
System.out.println("Calling the external system for employee "
+ execution.getVariable("employee"));
}
}