Activity工作流开发简单介绍
1. 工作流表
由图中可以看到,依赖中已经集成了mybatis框架,在第一次初始化流程引擎(ProcessEngine)时,会自动创建24张表(图示版本)。
act_evt_log,
act_ge_bytearray,
act_ge_property,
act_hi_actinst,
act_hi_attachment,
act_hi_comment,
act_hi_detail,
act_hi_identitylink,
act_hi_procinst,
act_hi_taskinst,
act_hi_varinst,
act_id_group,
act_id_info,
act_id_membership,
act_id_user,
act_re_deployment,
act_re_model,
act_re_procdef,
act_ru_event_subscr,
act_ru_execution,
act_ru_identitylink,
act_ru_job,
act_ru_task,
act_ru_variable
act_re_*
: 're’表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。act_ru_*
: 'ru’表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。act_id_*
: 'id’表示identity。 这些表包含身份信息,比如用户,组等等。act_hi_*
: 'hi’表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。act_ge_*
: 通用数据, 用于不同场景下。
参考:Activity工作流入门
重点介绍下一下几张表
act_ge_bytearray
:保存的工作流.bpmn
以及对应的图片.png
二进制文件act_re_deployment
:保存部署act_re_procdef
:保存部署的流程act_ru_execution
:保存等待执行的操作,包含启动、结束事件、任务、gateway流动等act_ru_task
:保存等待执行的任务act_ru_variable
:保存任务执行时定义的量act_hi_actinst
:保存所有执行(已执行和未执行)的操作,包含启动、结束事件、任务、gateway流动等act_hi_procinst
:保存部署的流程的历史act_hi_taskinst
:保存已经执行的任务
2. 实战
2.1 流程定义
定义一个网站开发的工作模式,开发工作准备好之后就同时让web端、server端、mobile端同时开发,所有的都完成后才算结束。(使用eclipse或者idea插件完成制图工作)
流程如图:
流程代码:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" 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:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1600330675002" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="devWebsite" isClosed="false" isExecutable="true" name="开发网站" processType="None">
<startEvent id="startevent1" name="start"/>
<userTask activiti:exclusive="true" id="startDev" name="开发"/>
<parallelGateway gatewayDirection="Unspecified" id="mutipathDevParallelGateway" name="多线路共同开发"/>
<userTask activiti:exclusive="true" id="webDev" name="web端"/>
<userTask activiti:exclusive="true" id="serverDev" name="server端"/>
<userTask activiti:exclusive="true" id="mobileDev" name="mobile端"/>
<endEvent id="endevent1" name="end"/>
<sequenceFlow id="_8" sourceRef="startevent1" targetRef="startDev"/>
<sequenceFlow id="_9" sourceRef="startDev" targetRef="mutipathDevParallelGateway"/>
<sequenceFlow id="_10" sourceRef="mutipathDevParallelGateway" targetRef="webDev"/>
<sequenceFlow id="_11" sourceRef="mutipathDevParallelGateway" targetRef="serverDev"/>
<sequenceFlow id="_2" sourceRef="mutipathDevParallelGateway" targetRef="mobileDev"/>
<sequenceFlow id="_3" sourceRef="webDev" targetRef="endevent1"/>
<sequenceFlow id="_4" sourceRef="serverDev" targetRef="endevent1"/>
<sequenceFlow id="_5" sourceRef="mobileDev" targetRef="endevent1"/>
</process>
<bpmndi:BPMNDiagram documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
<bpmndi:BPMNPlane bpmnElement="devWebsite">
<bpmndi:BPMNShape bpmnElement="startevent1" id="Shape-startevent1">
<omgdc:Bounds height="32.0" width="32.0" x="325.0" y="30.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="startDev" id="Shape-startDev">
<omgdc:Bounds height="55.0" width="85.0" x="305.0" y="135.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="mutipathDevParallelGateway" id="Shape-mutipathDevParallelGateway">
<omgdc:Bounds height="32.0" width="32.0" x="330.0" y="225.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="webDev" id="Shape-webDev">
<omgdc:Bounds height="55.0" width="85.0" x="190.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="serverDev" id="Shape-serverDev">
<omgdc:Bounds height="55.0" width="85.0" x="315.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="mobileDev" id="Shape-mobileDev">
<omgdc:Bounds height="55.0" width="85.0" x="430.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="Shape-endevent1">
<omgdc:Bounds height="32.0" width="32.0" x="340.0" y="465.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="_2" id="BPMNEdge__2" sourceElement="mutipathDevParallelGateway" targetElement="mobileDev">
<omgdi:waypoint x="362.0" y="241.0"/>
<omgdi:waypoint x="470.0" y="315.0"/>
<omgdi:waypoint x="470.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_3" id="BPMNEdge__3" sourceElement="webDev" targetElement="endevent1">
<omgdi:waypoint x="230.0" y="400.0"/>
<omgdi:waypoint x="230.0" y="440.0"/>
<omgdi:waypoint x="340.0" y="481.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_4" id="BPMNEdge__4" sourceElement="serverDev" targetElement="endevent1">
<omgdi:waypoint x="356.0" y="400.0"/>
<omgdi:waypoint x="356.0" y="465.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_5" id="BPMNEdge__5" sourceElement="mobileDev" targetElement="endevent1">
<omgdi:waypoint x="475.0" y="400.0"/>
<omgdi:waypoint x="475.0" y="425.0"/>
<omgdi:waypoint x="372.0" y="481.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="startevent1" targetElement="startDev">
<omgdi:waypoint x="341.0" y="62.0"/>
<omgdi:waypoint x="341.0" y="135.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="startDev" targetElement="mutipathDevParallelGateway">
<omgdi:waypoint x="346.0" y="190.0"/>
<omgdi:waypoint x="346.0" y="225.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_11" id="BPMNEdge__11" sourceElement="mutipathDevParallelGateway" targetElement="serverDev">
<omgdi:waypoint x="346.0" y="257.0"/>
<omgdi:waypoint x="346.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="mutipathDevParallelGateway" targetElement="webDev">
<omgdi:waypoint x="330.0" y="241.0"/>
<omgdi:waypoint x="230.0" y="310.0"/>
<omgdi:waypoint x="230.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
2.2 代码演示
1. 创建流程引擎
private ProcessEngine getProcessEngine() {
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
Properties properties = new Properties();
try {
properties = Resource.getClasspathProperties("activity.properties");
log.info("====================开始打印工作流配置=====================");
properties.forEach((key, value) -> System.out.println(key + "=" + value));
} catch (IOException e) {
e.printStackTrace();
}
configuration.setJdbcDriver(Resource.getProperty(properties, "activity.datasource.driver"));
configuration.setJdbcUrl(Resource.getProperty(properties, "activity.datasource.url"));
configuration.setJdbcUsername(Resource.getProperty(properties, "activity.datasource.username"));
configuration.setJdbcPassword(Resource.getProperty(properties, "activity.datasource.password"));
configuration.setDatabaseSchemaUpdate(Resource.getProperty(properties, "activity.databaseSchemaUpdate"));
return configuration.buildProcessEngine();
}
2. 部署流程
@Test
public void deployProcess() {
DeploymentBuilder deploymentBuilder = getProcessEngine().getRepositoryService().createDeployment();
deploymentBuilder.addClasspathResource("DevelopWebsite.bpmn");
Deployment deploy = deploymentBuilder.deploy();
System.out.println(StringUtil.format("============= 部署的流程ID为:{}=============", deploy.getId()));
}
3. 根据流程部署ID查询流程定义ID
@Test
public void queryProcessDefinition() {
String deployId = "1";
ProcessDefinitionQuery query = getProcessEngine().getRepositoryService().createProcessDefinitionQuery();
query.deploymentId(deployId);
query.list().forEach(item -> System.out.println(StringUtil.format("============ 流程定义ID为:{} ============", item.getId())));
}
4. 根据流程定义ID启动流程
/**
* @description: 根据流程定义ID启动流程,涉及到两张表:
* 1. act_ru_execution-记录未执行的进程记录,包含任务、gateway的执行,就像是指令。
* 2. act_ru_task:记录未执行的任务
* @author: yulin.chen
* @date: 2020/9/17 17:19
*/
@Test
public void startProcessByProcessDefinitionId() {
String processDefinitionId = "devWebsite:1:4";
ProcessInstance instance = getProcessEngine().getRuntimeService().startProcessInstanceById(processDefinitionId);
System.out.println(StringUtil.format("============ 启动的实例ID为:{} ============", instance.getId()));
}
5. 根据流程实例ID查询当前执行中的任务
@Test
public void queryRuntimeTasksByProcessInstanceId() {
String processInstanceId = "2501";
TaskQuery query = getProcessEngine().getTaskService().createTaskQuery();
//根据流程实例id查询
query.processInstanceId(processInstanceId);
//任务执行时间排序
query.orderByTaskCreateTime().desc();
query.list().forEach(item -> System.out.println(StringUtil.format("============ 正在执行的任务ID为:{},任务名:{} ============",
item.getId(), item.getName())));
}
6. 根据任务ID完成任务
@Test
public void execuTask() {
String taskId = "2504";
getProcessEngine().getTaskService().complete(taskId);
}
只有把命运掌握在自己手中,从今天起开始努力,即使暂时看不到希望,也要相信自己。因为比你牛几倍的人,依然在努力。