springboot接入flowable

分享:背景介绍(选取工作流的原因):
1.工作流应用现状
流程引导-》
权限审批(轻流)-》
一.工作流基本信息介绍
1.1 常用工作流的 flowable和activity是什么关系?
两个都是基于bpmn的工作流框架,区别是先有的acivity,然后开发团队独立出来基于activity开发的flowable,相对来说扩展性更好,开箱即用。
1.2 bpmn是什么?
BPMN 一般指业务流程建模标注。 业务流程建模标注(Business Process Modeling Notation,简称 BPMN )是一套规范标准,包括这些图元如何组合成一个业务流程图(Business Process Diagram)
1.3 使用flowable时需要了解的流程和概念。
完整的创建一个flowable并执行的过程中需要经历如下几个阶段。
1.节点设置
需要一个管理节点信息的管理页面,设置各个节点的属性。
节点属性可以分为如下几种:开始、结束、任务节点、线、排他网关、并行网关、包含网关
排他网关:类似if判断 只有满足条件的才会走向下一个节点,如果多条满足,也只会走计算速度最快的一条线。
并行网关:会全部执行后,再一同向下执行。即使设置条件判断,也会忽略条件。
包含网关:结合了排他网关和并行网关,满足条件就向下,不会限制数量。
2.构建流程图
3.后端流程模板保存部署
后端接收前端的数据(通过xml或者自定义数据结构),保存为模板(model)并且对模板启用进行部署(deployment)。
xml数据结构(不推荐对接使用,难以维护)
自定义数据结构举例(java)
4.启动实例
模板部署后,可以根据模板来启动实例,一个模板启动多个实例,各实例间互不影响。
5.任务(查看、完成、回退等)
流程实例启动后,可以查看到当前流程所处的任务节点,进行相关操作。
6.完成所有任务后,流程自动结束
1.4 flowable包含的数据库表
1.5 常用service分类
RepositoryService:很可能是使用Flowable引擎要用的第一个服务。这个服务提供了管理与控制部署(deployments)流程定义(process definitions)的操作
RuntimeService:用于启动流程定义的新流程实例。同一时刻,一个流程定义通常有多个运行中的实例。RuntimeService也用于读取与存储流程变量。流程变量是流程实例中的数据,可以在流程的许多地方使用(例如排他网关经常使用流程变量判断流程下一步要走的路径)。
TaskService:查询分派给用户或组的任务
HistoryService:暴露Flowable引擎收集的所有历史数据。当执行流程时,引擎会保存许多数据(可配置),例如流程实例启动时间、谁在执行哪个任务、完成任务花费的事件、每个流程实例的执行路径,等等。这个服务主要提供查询这些数据的能力。
二.springboot接入flowable
1.pom文件(只展示工作流相关)
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.7.2</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-engine</artifactId>
<version>6.7.2</version>
</dependency>
2.接收前端数据结构,本地mock数据 
@Data
public class CreateDeploymentDto {
/**
* 数据类型
* FlowConstant
*/
private String type;
/**
* 数据id,画线时根据这个id寻找前后节点
*/
private String id;
/**
* 名称
*/
private String name;
/**
* 线
* 起点
*/
private String source;
/**
* 线
* 终点
*/
private String target;
/**
* 条件表达式
*/
private String conditionExpression;
}
type类型
public class FlowConstant {
public static final String START_EVENT_TYPE = "START_EVENT";
public static final String END_EVENT_TYPE = "END_EVENT";
public static final String USER_TASK_TYPE = "USER_TASK";
public static final String LINE_TYPE = "LINE";
/**
* 排他网关
*/
public static final String EXCLUSIVE_GATEWAY = "EXCLUSIVE_GATEWAY";
/**
* 并行 网关
*/
public static final String PARALLEL_GATEWAY = "PARALLEL_GATEWAY";
/**
* 包含网关
* inclusive gateway
*/
public static final String INCLUSIVE_GATEWAY = "INCLUSIVE_GATEWAY";
}
构建测试数据
/**
* 组装测试数据 创建部署模板
*
* @return
*/
@Override
public List<CreateDeploymentDto> createDeployment() {
List<CreateDeploymentDto> resultList = new ArrayList<>();
resultList.add(makeStartData("start_id", "开始节点"));
resultList.add(makeEndData("end_id", "结束节点"));
resultList.add(makeUserTaskData("task_id_01", "任务1"));
resultList.add(makeUserTaskData("task_id_02", "任务2"));
resultList.add(makeLineData("start_id", "task_id_01",""));
resultList.add(makeLineData("task_id_01", "task_id_02",""));
resultList.add(makeLineData("task_id_02", "end_id",""));
log.info("组装测试数据 mockData:{}", resultList);
return resultList;
}
private CreateDeploymentDto makeStartData(String id, String name) {
CreateDeploymentDto dto = new CreateDeploymentDto();
dto.setType(FlowConstant.START_EVENT_TYPE);
dto.setId(id);
dto.setName(name);
return dto;
}
private CreateDeploymentDto makeEndData(String id, String name) {
CreateDeploymentDto dto = new CreateDeploymentDto();
dto.setType(FlowConstant.END_EVENT_TYPE);
dto.setId(id);
dto.setName(name);
return dto;
}
3.按照构建的数据,进行模板部署
//模型
BpmnModel bpmnModel = new BpmnModel();
//流程
Process process = new Process();
//流程id 对应 ACT_RE_PROCDEF key
process.setId("processId");
//流程id 对应 ACT_RE_PROCDEF name
process.setName("processName");
//
List<CreateDeploymentDto> mockDataList = mockData.createParallelDeployment();
makeProcessData(process, mockDataList);
bpmnModel.addProcess(process);
//model转为xml,可以在这里反向存到model表中
byte[] xml = new BpmnXMLConverter().convertToXML(bpmnModel);
//校验
new BpmnXMLConverter().validateModel(new InputStreamSource(new ByteArrayInputStream(xml)));
//创建部署 ACT_RE_DEPLOYMENT对应 name字段
Deployment deployment = repositoryService.createDeployment().name("deploymentName").addString("test.bpmn20.xml", new String(xml)).deploy();
log.info("创建部署模板成功 createDeployment success,deploymentKey:{}", deployment.getKey());
执行完后可以在 ACT_RE_PROCDEF中查看数据
如何设置网关?
@Override
public List<CreateDeploymentDto> createExclusiveDeployment() {
List<CreateDeploymentDto> resultList = new ArrayList<>();
resultList.add(makeStartData("start_id", "开始节点"));
resultList.add(makeEndData("end_id", "结束节点"));
resultList.add(makeUserTaskData("task_id_01", "任务1"));
resultList.add(makeUserTaskData("task_id_02", "任务2"));
resultList.add(makeUserTaskData("task_id_03", "任务3"));
resultList.add(makeExclusiveData("exclusive_gateway","排他网关"));
resultList.add(makeLineData("start_id", "task_id_01",""));
resultList.add(makeLineData("task_id_01", "exclusive_gateway",""));
resultList.add(makeLineData("exclusive_gateway", "task_id_02","${testVar==10}"));
resultList.add(makeLineData("exclusive_gateway", "task_id_03","${testVar==50}"));
resultList.add(makeLineData("task_id_02", "end_id",""));
resultList.add(makeLineData("task_id_03", "end_id",""));
log.info("组装测试数据 mockData:{}", resultList);
return resultList;
}
@Override
public List<CreateDeploymentDto> createParallelDeployment() {
List<CreateDeploymentDto> resultList = new ArrayList<>();
resultList.add(makeStartData("start_id", "开始节点"));
resultList.add(makeEndData("end_id", "结束节点"));
resultList.add(makeUserTaskData("task_id_01", "任务1"));
resultList.add(makeUserTaskData("task_id_02", "任务2"));
resultList.add(makeUserTaskData("task_id_03", "任务3"));
resultList.add(makeUserTaskData("task_id_04", "任务4"));
resultList.add(makeParallelData("parallel_gateway_start","并行网关"));
resultList.add(makeParallelData("parallel_gateway_end","并行网关"));
resultList.add(makeLineData("start_id", "task_id_01",""));
resultList.add(makeLineData("task_id_01", "parallel_gateway_start",""));
resultList.add(makeLineData("parallel_gateway_start", "task_id_02",""));
resultList.add(makeLineData("parallel_gateway_start", "task_id_03",""));
resultList.add(makeLineData("task_id_02", "parallel_gateway_end",""));
resultList.add(makeLineData("task_id_03", "parallel_gateway_end",""));
resultList.add(makeLineData("parallel_gateway_end", "task_id_04",""));
log.info("组装测试数据 mockData:{}", resultList);
return resultList;
}
4.根据模板信息(key)启动流程实例
普通流程 不需要携带流程变量
/**
* 根据key启动流程实例
*/
@Override
public void startProcByKey(String key) {
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key);
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
log.info("启动流程processInstance:{},当前任务taskId:{}", processInstance.getId(), task.getId());
}
需要携带流程变量,用于排他网关的判断 
* 根据key启动流程实例
* 携带流程变量
*/
@Override
public void startProcByKeyWithVar(String key) {
Map<String, Object> variables = new HashMap<>();
variables.put("testVar", 50);
ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder().
processDefinitionKey(key).
variables(variables).
start();
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
log.info("启动流程processInstance:{},当前任务taskId:{}", processInstance.getId(), task.getId());
}
启动后在ACT_RU_TASK中可以查看任务数据
4.根据任务信息 完成任务/回退任务
/**
* 完成任务
*
* @param id
*/
@Override
public void completeTask(String id) {
taskService.complete(id);
log.info("完成任务id:{}", id);
}
@Override
public void changeTaskPoint(String procInstanceId, String sourceTargetDefKey, String targetTaskDefKey) {
runtimeService.createChangeActivityStateBuilder().processInstanceId(procInstanceId)
.moveActivityIdTo(sourceTargetDefKey, targetTaskDefKey).changeState();
log.info("回退任务");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值