Flowable流程定义demo
<?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:flowable="http://flowable.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"
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.flowable.org/processdef">
<process id="my_leave" name="my_leave" isExecutable="true">
<userTask id="leaveTask" name="这是我的测试请假xml" flowable:assignee="#{leaveTask}"/>
<userTask id="zuzhangTask" name="组长审核" flowable:assignee="#{zuzhangTask}"/>
<userTask id="managerTask" name="经理审核" flowable:assignee="#{managerTask}"/>
<exclusiveGateway id="managerJudgeTask"/>
<exclusiveGateway id="zuzhangJudeTask"/>
<endEvent id="endLeave" name="结束"/>
<startEvent id="startLeave" name="开始"/>
<sequenceFlow id="flowStart" sourceRef="startLeave" targetRef="leaveTask"/>
<sequenceFlow id="modeFlow" sourceRef="leaveTask" targetRef="zuzhangTask"/>
<sequenceFlow id="zuzhang_go" sourceRef="zuzhangJudeTask" targetRef="managerTask" name="通过">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkResult=='通过'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="zuzhang_reject" sourceRef="zuzhangJudeTask" targetRef="sendMail" name="拒绝">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkResult=='拒绝'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="jugdeFlow" sourceRef="managerTask" targetRef="managerJudgeTask"/>
<sequenceFlow id="flowEnd" name="通过" sourceRef="managerJudgeTask" targetRef="endLeave">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkResult=='通过'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="rejectFlow" name="拒绝" sourceRef="managerJudgeTask" targetRef="sendMail">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkResult=='拒绝'}]]></conditionExpression>
</sequenceFlow>
<serviceTask id="sendMail" flowable:exclusive="true" name="发送失败提示" isForCompensation="true"
flowable:class="com.flowable.test.modules.leave.AskForLeaveFail"/>
<sequenceFlow id="endFlow" sourceRef="sendMail" targetRef="askForLeaveFail"/>
<endEvent id="askForLeaveFail" name="请假失败"/>
<sequenceFlow id="zuzhangTask_zuzhangJudeTask" sourceRef="zuzhangTask" targetRef="zuzhangJudeTask"/>
</process>
</definitions>
以上是基于BPMN模型构建的flowable定义信息。 现在看到是xml形式。 但在使用的时候会以zip文件或其他形式进行包装。 以更好的进行传输或导入导出操作。
那么什么是部署?
简单: 就是解析各种不同形式的流程定义文件。 将其导入数据库,形成数据记录。 作为流程发起的引用。
流程定义相关表
| 数据表 | 描述 | 版本 |
|---|---|---|
| ACT_GE_BYTEARRAY | 保存和流程引擎相关的资源,只要调用了Activiti存储服务的API,涉及的资源均会被转换为byte数组保存到这个表中,部署几次就会有几条记录 | 6.7.2 |
| ACT_GE_PROPERTY | 流程全部的属性抽象为key-value对,每个属性都有名称和值。 | 6.7.2 |
| act_re_model | 模型信息表(用于Web设计器)--ModelEntityImpl | 6.7.2 |
| act_re_deployment | 流程部署表--DeploymentEntityImpl | 6.7.2 |
| act_re_procdef | 流程定义信息表--ProcessDefinitionEntityImpl | 6.7.2 |
- 流程资源模型说明
流程定义文件:文件的命名必须是XXXXbpmn20.xml,注意命名规范,后面必须是bpmn20.xml。
流程定义图片:用BPMN2.0规范定义的各种图形描绘(BMPN2.0的符号及画布上的坐标信息),一般是PNG格式。
表单文件:把表单内容保存在一个文件中,扩展名为drl。
规则文件:扩展名为drl。
- 流程模型资源的部署
1. 导出xml,然后部署到flowable数据库中
2. 多个流程模型定义文件,即xml打包成zip/bar,多个资源文件一起部署。
3. Model方式部署,设计器中的发布就是用的此方法。
4. 其它方式部署
流程部署方式
从ClassPath中获取部署文件
@Autowired
private RepositoryService repositoryService;
/**
* 部署工作流程
*
* @param filePath 文件路径(classpath下的文件名称,注意不是路径)
* @return Deployment 部署对象
*/
public Deployment deployFlow(String fileName) {
try {
DeploymentBuilder deploymentBuilder = repositoryService
.createDeployment()
.addClasspathResource(fileName);
Deployment deployment = deploymentBuilder.deploy();
log.info("成功:部署工作流成:" + filePath);
return deployment;
} catch (Exception e) {
log.error("失败:部署工作流:" + e);
return null;
}
}
在这个业务执行会在数据库相应的表结构进行数据生成。 主要如下:
//先生成部署记录
select * from act_re_deployment where ID_ ="16fe96cf-ced6-11ed-9af4-a2c54ef84c48";
//将xml资源存储在这个表中
select * from act_ge_bytearray where DEPLOYMENT_ID_ ="16fe96cf-ced6-11ed-9af4-a2c54ef84c48";
//生成流程定义数据,其主键ID_会作为act_ru_*,act_hi_* 相关表PROC_DEF_ID的键。这样就可以约束流程运行
select * from act_re_procdef where DEPLOYMENT_ID_ ="16fe96cf-ced6-11ed-9af4-a2c54ef84c48";
基于设计器生成流程并且部署
@GetMapping("deployByModelId")
public Result<String> deployByModelId(String modelId) {
Model model = modelService.getModel(modelId);
BpmnModel bpmnModel = modelService.getBpmnModel(model);
Deployment deployment = repositoryService.createDeployment()
.name(model.getName())
.addBpmnModel(model.getKey() + ".bpmn", bpmnModel).deploy();
String deploymentId = deployment.getId(); //部署ID
return Results.newSuccessResult(modelId);
}
基于ZIP文件进行流程部署
@GetMapping
public Result<String> deployByZip(String name, String zipPath) throws Exception {
File outfile = new File(zipPath);
FileInputStream inputStream = new FileInputStream(outfile);
ZipInputStream ipInputStream = new ZipInputStream(inputStream);
//创建部署对象
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
//部署名称
deploymentBuilder.name(name);
deploymentBuilder.addZipInputStream(ipInputStream);
//完成部署
Deployment deployment = deploymentBuilder.deploy();
ipInputStream.close();
inputStream.close();
//部署ID
return Results.newSuccessResult(deployment.getId());
}
关于版本的控制问题
问:如果一个流程进行修改。但名称和id不变。如何保证正在进行的流程不受影响? 答: act_re_procdef 主要是这张表通过版本号进行控制。