设计流程图
我们先画一个图,如下:
查看bpmn文件
bpmn全称为 业务流程建模与标注(Business Process Model and Notation) ,用来描述一个业务流程图怎么组合成的
在Eclipse里面右键 Open With —> XML Editor 查看流程图文件的bpmn文档
<?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: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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test" id="m1528372471453" name="">
<process id="myProcess_1" name="请假申请" isExecutable="true" isClosed="false" processType="None">
<startEvent id="StartEvent" name="StartEvent"></startEvent>
<endEvent id="EndEvent" name="EndEvent"></endEvent>
<userTask id="task1" name="提交申请(李晨)" activiti:assignee="李晨"></userTask>
<userTask id="task2" name="审批【部门经理冯小刚】" activiti:assignee="冯小刚"></userTask>
<userTask id="task3" name="审批【总经理周星驰】" activiti:assignee="周星驰"></userTask>
<sequenceFlow id="_7" sourceRef="StartEvent" targetRef="task1"></sequenceFlow>
<sequenceFlow id="_8" sourceRef="task1" targetRef="task2"></sequenceFlow>
<sequenceFlow id="_9" sourceRef="task2" targetRef="task3"></sequenceFlow>
<sequenceFlow id="_10" sourceRef="task3" targetRef="EndEvent"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_myProcess_1">
<bpmndi:BPMNPlane bpmnElement="myProcess_1" id="BPMNPlane_myProcess_1">
<!--
这里记录了开始节点和结束节点,以及三个任务节点的坐标位置还有大小信息
例如:<omgdc:Bounds height="35.0" width="35.0" x="512.0" y="102.0"></omgdc:Bounds>
height="35.0" width="35.0" 分别指的是开始节点的高度和宽度
x="512.0" y="102.0" 分别指的是开始节点的坐标位置
这些记录是为了在流程运行中,红色方框(提示)的显示,例如流程运行的到第一个任务节点了,
那么提示就会根据上面XML中第一个节点记录的位置信息在相应的位置显示出红色方框(提示)
-->
<bpmndi:BPMNShape bpmnElement="StartEvent" id="BPMNShape_StartEvent">
<omgdc:Bounds height="35.0" width="35.0" x="512.0" y="102.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="EndEvent" id="BPMNShape_EndEvent">
<omgdc:Bounds height="35.0" width="35.0" x="512.0" y="520.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="task1" id="BPMNShape_task1">
<omgdc:Bounds height="55.0" width="112.0" x="474.0" y="190.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="task2" id="BPMNShape_task2">
<omgdc:Bounds height="55.0" width="162.0" x="449.0" y="291.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="task3" id="BPMNShape_task3">
<omgdc:Bounds height="55.0" width="170.0" x="445.0" y="401.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="_7" id="BPMNEdge__7">
<omgdi:waypoint x="529.0" y="137.0"></omgdi:waypoint>
<omgdi:waypoint x="530.0" y="190.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8">
<omgdi:waypoint x="530.0" y="245.0"></omgdi:waypoint>
<omgdi:waypoint x="530.0" y="291.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9">
<omgdi:waypoint x="530.0" y="346.0"></omgdi:waypoint>
<omgdi:waypoint x="530.0" y="401.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10">
<omgdi:waypoint x="530.0" y="456.0"></omgdi:waypoint>
<omgdi:waypoint x="529.0" y="520.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
说明:流程定义文档有两部分组成:
- bpmn文件
流程规则文件。在部署后,每次系统启动时都会被解析,把内容封装成流程定义放入项目缓存中。Activiti框架结合这个xml文件自动管理流程,流程的执行就是按照bpmn文件定义的规则执行的,bpmn文件是给计算机执行用的。 - 展示流程图的图片
在系统里需要展示流程的进展图片,图片是给用户看的。
部署流程定义
先获取流程引擎对象:在创建时会自动加载classpath下的activiti.cfg.xml(Activiti源码里面默认加载名称为“activiti.cfg.xml”的文件)
部署方法一,从classpath加载
// 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**
* 部署流程定义(从classpath文件加载)
*/
@Test
public void deploymentProcessDefinition(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService() // 与流程定义和部署相关的Service
.createDeployment() // 创建一个部署对象
.name("流程定义文件2") // 添加部署的名称
.addClasspathResource("diagrams/test1.bpmn") // 从classpath的资源文件中加载,一次只能加载一个文件
.addClasspathResource("diagrams/test1.png")
.deploy(); // 完成部署,完成之后返回一个部署对象
System.out.println("流程部署id:"+deployment.getId());
System.out.println("部署名称:"+deployment.getName());
}
流程部署操作会操作以下3张表:
-
act_re_deployment(流程部署信息表)
存放流程定义的显示名和部署时间,每部署一次增加一条记录 -
act_re_procdef(流程定义数据表 )
存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录。当流程定义的key相同的情况下,使用的是版本升级 -
act_ge_bytearray(资源文件表)
存储流程定义相关的存放地址信息。每部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片的(如果部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图)。两个文件不是很大,都是以二进制形式存储在数据库中。
每次部署一次文件,act_ge_property 表里面的value值就会改变,作为下一次部署文件的“流程部署id”,act_ge_property (主键生成策略表)初始化表结构时,会默认插入三条记录
我们右键 Run As —> JUnit Test运行单元测试,输出结果如下:
我们看看act_re_deployment(流程部署信息表),已经成功的插入了一条信息
act_re_procdef(流程定义数据表 )
act_ge_bytearray(资源文件表)也有了两条数据,一条是流程定义文件的路径,一条是流程图图片的路径
我们再来部署第二次,再看看这三张表的变化:
我们看看act_re_deployment(流程部署信息表)
act_re_procdef(流程定义数据表 )
act_ge_bytearray(资源文件表)
部署方法二,从zip文件加载
我们将test1.bpmn文件和test1.png文件打包成为zip文件,然后复制到项目里面进行测试
/**
* 部署流程定义(从ZIP文件加载)
*/
@Test
public void deploymentProcessDefinition_ZIP(){
InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/testZIP.zip");
ZipInputStream zipInputStream = new ZipInputStream(in);
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService() // 与流程定义和部署相关的Service
.createDeployment() // 创建一个部署对象
.name("流程定义文件zip") // 添加部署的名称
.addZipInputStream(zipInputStream) // 指定zip的文件完成部署
.deploy(); // 完成部署,完成之后返回一个部署对象
System.out.println("流程部署id:"+deployment.getId());
System.out.println("部署名称:"+deployment.getName());
}
我们右键 Run As —> JUnit Test运行单元测试,运行成功后输出结果如下:
现在运行成功了,我们来看看act_re_procdef(流程定义数据表 ),现在多出了一条数据,act_re_procdef每部署一次就会插入一条数据
再来看看act_re_procdef(流程定义数据表 )
act_ge_bytearray(资源文件表)