springboot集成camunda学习与使用
springboot集成camunda学习与使用.md
- 0、前言
- 一、Spring Boot 集成camunda流程引擎
- 1.新建全新的springboot工程
- 2.添加pom.xml依赖
- 3.启动Spring Boot工程
- 4.切换成mysql数据库
- 5.设计并部署一个BPMN流程
- 6.camunda流程引擎测试
- 6.1 通过camunda web控制台测试
- 6.2 通过camunda rest接口测试
- 6.3 通过Java API接口测试
- 二、自建BPMN Web Modeler
0、前言
Camunda是一款开源的业务流程管理(BPM)平台,旨在帮助企业自动化和优化他们的业务流程。Camunda的核心功能包括流程设计、执行和监控,支持BPMN(业务流程模型与标注)、CMMN(案例管理模型与标注)和DMN(决策模型与标注)等标准。
一、Spring Boot 集成camunda流程引擎
本文内容参考此文总结得出:https://blog.csdn.net/wxz258/article/details/136279524
1.新建全新的springboot工程
新建一个springboot工程,springboot版本为2.7.18,jdk版本1.8,过程略。
2.添加pom.xml依赖
为新项目设置 Maven 依赖项。需要将 Maven 依赖添加到项目,添加后支持camunda流程引擎、web界面、Rest服务接口,导入camunda-bpm-spring-boot-starter-rest、camunda-bpm-spring-boot-starter-webapp依赖包。导入后自动将camunda 引擎、rest服务接口和 Web应用程序包含在springboot工程。
使用camunda7.19.0版本,该版本支持jdk8和springboot2。camunda和springboot版本的依赖对应关系,查看官方文档说明:Spring Boot Version Compatibility | docs.camunda.org
- pom.xml增加依赖
<!-- camunda start -->
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
<version>${camunda.spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
<version>${camunda.spring-boot.version}</version>
</dependency>
<!-- camunda end -->
<!-- spring jdbc start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- spring jdbc end -->
<!-- h2database start -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- h2database end -->
注:需要添加spring-boot-starter-jdbc依赖,否则会报Field transactionManager in org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultDatasourceConfiguration required a bean of type ‘org.springframework.transaction.PlatformTransactionManager’ that could not be found.
- application.yml中增加配置
spring:
datasource:
url: jdbc:h2:mem:camunda;DB_CLOSE_DELAY=1000;LOCK_TIMEOUT=10000
username: sa
password:
driver-class-name: org.h2.Driver
camunda:
bpm:
database:
type: h2 #可改成 mysql
schema-update: true
auto-deployment-enabled: false # 自动部署 resources 下的 bpmn文件
admin-user:
id: demo
password: demo
3.启动Spring Boot工程
以上增加依赖后,就可以基于内存数据库(h2)在本地启动好camunda流程引擎了,启动后,在浏览器中打开 http://localhost:8080/ 时,您可以使用我们之前配置的登录名和密码"demo/demo"来访问 Camunda Web应用程序,能做到下面效果说明成功。
4.切换成mysql数据库
如果camunda要在生产环境中使用,不太可能是直接使用h2数据库的,camunda本身对mysql的支持性也相当好,因此需要改造一下切换成使用mysql.
其他数据库的支持情况见:https://docs.camunda.org/manual/7.19/introduction/supported-environments/#databases
- pom.xml增加mysql依赖
<!-- mysql driver start -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- mysql driver end -->
- application.yml中修改
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/camundatest?characterEncoding=UTF-8&useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
camunda:
bpm:
database:
type: mysql
schema-update: false # 是否自动建表,但我测试为true时,创建表会出现,因此还是改成false由手工建表。
auto-deployment-enabled: false # 自动部署 resources 下的 bpmn文件
admin-user:
id: demo
password: demo
- mysql中创建数据库camundatest
create database camundatest;
- 生成数据库表
使用schma-update:true后,启动工程也不会完全生成完整的mysql表,原因不明,因此还是采用手工执行数据库脚本的方式来建表。
Sql建表语句位置:找到maven依赖,org\camunda\bpm\camunda-engine\7.19.0\camunda-engine-7.19.0.jar,org.camunda.bpm.engine.db.create包下面。
/org/camunda/bpm/engine/db/create/activiti.mysql.create.case.engine.sql
/org/camunda/bpm/engine/db/create/activiti.mysql.create.case.history.sql
/org/camunda/bpm/engine/db/create/activiti.mysql.create.decision.engine.sql
/org/camunda/bpm/engine/db/create/activiti.mysql.create.decision.history.sql
/org/camunda/bpm/engine/db/create/activiti.mysql.create.engine.sql
/org/camunda/bpm/engine/db/create/activiti.mysql.create.history.sql
/org/camunda/bpm/engine/db/create/activiti.mysql.create.identity.sql
使用navicat或其他工具依次执行完。注:我测试的时候其中activiti.mysql.create.case.engine.sql有部分sql执行报错,提示重复创建之类的,那就把报错的sql一一删除再执行完。
最后得到49张表.
最后再执行一下springboot工程重启成功。再一次进行http://localhost:8080测试,输入demo/demo能登录成功。
5.设计并部署一个BPMN流程
这里先使用windows下载安装的流程设计器进行一个流程设计与测试,后面章面再说明如果通过web构建一个浏览器形式的在线流程设计器。
- 下载安装流程设计器
windows版本下载地址:https://downloads.camunda.cloud/release/camunda-modeler/5.19.0/camunda-modeler-5.19.0-win-x64.zip
下载后得到一个zip,解压后即可运行Camunda Modeler.exe使用。
- 设计BPMN流程
点击后会提示保存xml,然后出现以下弹窗,配置好REST endpoint,然后点Deploy即可发布成功。
发布成功后会在act_ge_bytearray,act_re_deployment表中生成对应的数据
6.camunda流程引擎测试
6.1 通过camunda web控制台测试
现在,当您在浏览器中打开 http://localhost:8080/camunda/app/tasklist/ 时,您可以使用我们之前配置的登录名和密码“demo/demo”来访问 Camunda Web 应用程序。
可以点击Start process进行流程的启动
Start process后:act_hi_procinst表中会有新的一条流程实例数据,对应的act_ru_task和act_hi_taskinst等表均有相应的记录
6.2 通过camunda rest接口测试
以上我们通过camunda的web界面进行了发起流程测试验证,下面我们通过Camunda REST API的方式进行测试验证。
Camunda Platform REST API官方说明文档:https://docs.camunda.org/rest/camunda-bpm-platform/7.19/
- 查询流程定义
GET http://{host}:{port}/{contextPath}/process-definition
# 示例
curl http://localhost:8080/engine-rest/process-definition
# 输出
[{"id":"Process_0woc0aw:1:711f5f2d-5c38-11ef-9f87-e46017b79329","key":"Process_0woc0aw","category":"http://bpmn.io/schema/bpmn","description":null,"name":null,"version":1,"resource":"diagram_1.bpmn","deploymentId":"7104f95b-5c38-11ef-9f87-e46017b79329","diagram":null,"suspended":false,"tenantId":null,"versionTag":null,"historyTimeToLive":180,"startableInTasklist":true}]
- 查询流程定义数量
GET http://{host}:{port}/{contextPath}/process-definition/count
curl http://localhost:8080/engine-rest/process-definition/count
- 发起流程实例(流程启动)
POST http://{host}:{port}/{contextPath}/process-definition/key/{key}/start
# 示例
curl -X POST -H 'Content-Type: application/json' \
-d '{
"variables": {
"variable1": {
"value": "hello",
"type": "String"
},
"variable2": {
"value": true,
"type": "Boolean"
}
},
"businessKey": "myBusinessKey-test1"
}' \
"http://localhost:8080/engine-rest/process-definition/key/Process_0woc0aw/start"
# 输出
{"links":[{"method":"GET","href":"http://localhost:8080/engine-rest/process-instance/7aac2fb7-5c48-11ef-9f87-e46017b79329","rel":"self"}],"id":"7aac2fb7-5c48-11ef-9f87-e46017b79329","definitionId":"Process_0woc0aw:1:711f5f2d-5c38-11ef-9f87-e46017b79329","businessKey":"myBusinessKey-test1","caseInstanceId":null,"ended":false,"suspended":false,"tenantId":null}
- 查询待办任务
GET http://{host}:{port}/{contextPath}/task
# 示例
# 查询所有待办任务
curl http://localhost:8080/engine-rest/task
# 查询分配给liujh的待办任务
curl http://localhost:8080/engine-rest/task?assignee=liujh
[{"id":"7aaec7ce-5c48-11ef-9f87-e46017b79329","name":"审批","assignee":"liujh","created":"2024-08-17T11:26:24.000+0800","due":null,"followUp":null,"lastUpdated":null,"delegationState":null,"description":null,"executionId":"7aac2fb7-5c48-11ef-9f87-e46017b79329","owner":null,"parentTaskId":null,"priority":50,"processDefinitionId":"Process_0woc0aw:1:711f5f2d-5c38-11ef-9f87-e46017b79329","processInstanceId":"7aac2fb7-5c48-11ef-9f87-e46017b79329","taskDefinitionKey":"Activity_0p57gxb","caseExecutionId":null,"caseInstanceId":null,"caseDefinitionId":null,"suspended":false,"formKey":null,"camundaFormRef":null,"tenantId":null},{"id":"b11eed80-5c39-11ef-9f87-e46017b79329","name":"审批","assignee":"liujh","created":"2024-08-17T09:40:33.000+0800","due":null,"followUp":null,"lastUpdated":null,"delegationState":null,"description":null,"executionId":"b1148d3d-5c39-11ef-9f87-e46017b79329","owner":null,"parentTaskId":null,"priority":50,"processDefinitionId":"Process_0woc0aw:1:711f5f2d-5c38-11ef-9f87-e46017b79329","processInstanceId":"b1148d3d-5c39-11ef-9f87-e46017b79329","taskDefinitionKey":"Activity_0p57gxb","caseExecutionId":null,"caseInstanceId":null,"caseDefinitionId":null,"suspended":false,"formKey":null,"camundaFormRef":null,"tenantId":null}]
- 完成待办任务
POST http://{host}:{port}/{contextPath}/task/{id}/complete
curl -X POST -H 'Content-Type: application/json' \
-d '{
"variables": {
"variable1": {
"value": "agree",
"type": "String"
}
}
}' \
"http://localhost:8080/engine-rest/task/d2925d3f-5c49-11ef-9f87-e46017b79329/complete"
6.3 通过Java API接口测试
- 流程引擎接口实现相关引入
/**
* 流程定义相关接口实现类
*/
@Resource
private RepositoryService repositoryService;
/**
* 流程实例相关接口实现类
*/
@Resource
private RuntimeService runtimeService;
/**
* 任务相关接口实现类
*/
@Resource
private TaskService taskService;
/**
* 身份相关服务
*/
@Resource
private IdentityService identityService;
- 查询所有的流程定义
/**
* 获取所有的流程定义
* @return
*/
@GetMapping("/getProcessDefinitions")
public List<String> getProcessDefinitions() {
// 创建流程定义查询并列出所有的流程定义
List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().list();
// 定义输出变量
List<String> definitionKeys = new ArrayList<String>();
// 输出流程定义信息
for (ProcessDefinition processDefinition : processDefinitions) {
System.out.println("Process Definition ID: " + processDefinition.getId());
System.out.println("Process Definition Key: " + processDefinition.getKey());
System.out.println("Process Definition Name: " + processDefinition.getName());
System.out.println("Version: " + processDefinition.getVersion());
System.out.println("-------------------------------------------------");
// 加入definitionKeys
definitionKeys.add(processDefinition.getKey());
}
return definitionKeys;
}
- 查询流程定义数量
/**
* 获取所有的流程定义的数量
*
* @return 流程定义的数量
*/
@GetMapping("/getProcessDefinitionCount")
public Long getProcessDefinitionCount() {
// 创建流程定义查询并列出所有的流程定义个数
Long processDefinitionCount = repositoryService.createProcessDefinitionQuery().count();
// 输出结果
System.out.println("Process Definition size: " + processDefinitionCount);
return processDefinitionCount;
}
- 发起流程实例(流程启动)
/**
* 发起流程实例(流程启动)
*
* @param procDefKey 业务Key
* @return
*/
@GetMapping("/processInstanceStart")
public String processInstanceStart(@NotBlank(message = "业务Key不能为空") String businessKey) {
// 流程定义Key
String procDefKey = "Process_0woc0aw";
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(procDefKey, businessKey);
// 输出结果
System.out.println(processInstance.getProcessInstanceId());
return processInstance.getProcessInstanceId();
}
- 查询待办任务
使用TaskService进行待办任务查询
/**
* 查询待办任务(分配置assigee的所有任务)
* 测试:curl http://localhost:8080/camundaTest/listTasks?assignee=liujh
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@GetMapping("/listTasks")
public List<String> listTasks(@NotBlank(message = "assignee不能为空") String assignee) {
// 定义返回结果变量list
List<String> taskIds = new ArrayList<>();
// 列表用户assignee下的当前所有的待办任务列表
List<TaskEntity> taskList = (List) taskService.createTaskQuery().taskAssignee(assignee).list();
for (Task task : taskList) {
String taskTitle = "待办任务ID=" + task.getId() + ",流程实例ID=" + task.getProcessInstanceId() + "\n";
System.out.println(taskTitle);
taskIds.add(task.getId());
}
return taskIds;
}
- 完成待办任务
/**
* 完成待办任务,这里仅测试,正式环境需要写到Service层并且写在同一事务
*/
@GetMapping("/completeTask")
public void completeTask(@NotBlank(message = "任务ID不能为空") String taskId,
@NotBlank(message = "任务处理人不能为空") String assignee) {
// 工作流程传递变量定义
Map<String, Object> variables = new HashMap<>();
variables.put("approved", true);
// 根据任务Id查询出相关信息
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if(task == null) {
throw new RuntimeException("未找到任务Id为 " + taskId + " 的任务");
}
// 设置当前线程的用户身份,用于增加批注信息时设置用户ID
identityService.setAuthenticatedUserId(assignee);
// 完成任务
taskService.complete(taskId, variables);
// 增加批注信息
taskService.createComment(taskId, task.getProcessInstanceId(), "同意~");
}
二、自建BPMN Web Modeler
Camunda Modeler如何在web浏览器上设计?
第一章节中的流程设计器是直接采用在windows下下载流程设计器安装程序在本机上使用的,但往往希望在浏览器上跟随应用系统部署在一起,形成一个web版的在线设计器。
我公司的大部分项目是使用react的,因此这里就使用开源的BPMN建模库,如:Bpmn.js + react,结合后台java接口来完成。
思路:
- 1.前端开发
使用bpmn-js构建一个BPMN流程设计器。
提供流程元素的拖拽、连线、属性编辑等功能。
支持流程的保存、加载和导出为BPMN XML格式。
- 2.后端开发
使用Spring Boot等技术搭建后端服务。
提供API接口来保存用户设计的BPMN XML文件。
提供接口将BPMN文件部署到Camunda流程引擎。
支持版本管理和用户权限管理。
自建BPMN Web Modeler未完成待补充