简单易懂的Spring Boot整合Camunda7入门教程
因为关于Spring Boot结合Camunda7的教程在网上比较少,而且很多都写得有点乱,很多概念写得太散乱,讲解不清晰,导致看不懂,本人通过研究学习之后就写出了这篇教学文档。
介绍
Camunda是一个开源平台,专为开发人员设计,用以建模、执行和监控业务流程。它基于BPMN(Business Process Model and Notation,业务流程建模与标记)标准,允许组织自动化其业务流程。Camunda的核心组件包括流程引擎、任务管理器、用户界面组件和管理工具。
官方文档
为什么结合Spring Boot和Camunda?
- 简化开发:Spring Boot简化了Java应用的搭建过程,而Camunda则提供了强大的流程自动化工具。两者的结合可以帮助开发者快速搭建带有工作流的应用。
- 集成便利:Spring Boot和Camunda都有很好的生态支持,它们之间的集成相对简单,因为Camunda本身也支持Spring环境。
- 灵活性和可扩展性:Camunda允许在流程定义中嵌入自定义Java代码,这样可以轻松地与现有的Spring Boot应用集成,实现复杂的业务逻辑。
快速开始
添加依赖
环境为java17
添加依赖:
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter</artifactId>
<version>7.18.0</version>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
<version>7.18.0</version>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
<version>7.18.0</version>
</dependency>
camunda-bpm-spring-boot-starter
这个依赖包是Camunda与Spring Boot集成的基础,包含了启动Camunda BPM引擎所需的基本组件,如Camunda BPM Engine、Spring Integration以及Spring Boot自动配置。它使开发者能够快速启动Camunda BPM引擎,并提供默认配置选项。
camunda-bpm-spring-boot-starter-rest
此依赖包提供了Camunda REST API的支持,允许通过HTTP请求访问Camunda BPM引擎的功能,如启动流程实例、查询状态、管理任务及部署定义。这使得前端应用或其他服务可以通过RESTful方式与Camunda交互。
camunda-bpm-spring-boot-starter-webapp
这个依赖包用于创建集成Camunda Web客户端(如Cockpit)和任务列表(Tasklist)的Web应用程序,方便在浏览器中管理和监控Camunda流程。这提高了开发和运维的效率。
基础配置
# Camunda Engine自动配置
camunda:
db:
history: full
# camunda登录信息配置
camunda.bpm:
auto-deployment-enabled: false # 关闭自动部署,一开始测试的时候可以先不关闭,默认是自动部署
admin-user:
id: admin #用户名
password: 123456 #密码
firstName: su
filter:
create: All tasks
至少要配置一个数据库项(mysql,pgsql都支持):
datasource:
driver-class-name: org.postgresql.Driver
username:
password:
url: jdbc:postgresql:
jpa:
hibernate:
ddl-auto: update
resources下新建BPMN用于存放流程文件:
启动项目
配置好之后,启动项目,会自动配置好数据库和生成对应表
通过localhost:端口号/context-path(自己配置的,没有可以忽略)/camunda/app/,可以访问到内置web界面
输入用户名密码即为配置文件里面的 admin,123456
主控制台
登陆成功后,如下所示,具体的使用在下面介绍
- Cockpit:这是Camunda的管理控制台,用于监视和调试流程实例。你可以在这里查看流程定义、流程实例、历史数据等。它是开发人员和管理员的主要工具,用于理解流程行为和诊断问题。
- Tasklist:这是一个任务列表,用于查看和管理当前待办事项。对于那些需要完成任务的用户来说,这是一个重要的入口点。
- Admin:这是Camunda的管理工具,用于管理用户、组、权限和数据库连接等。它提供了对系统设置的全面控制。
绘制流程图
下载
首先需要一个工具 Camunda Modeler 来画,下载地址:
https://camunda.com/download/modeler/
选择对应自己电脑的版本下载:
下载好后,解压双击打开程序:
新建流程图
最终绘制一个基础的任务审核流程图:
介绍
任务分类
介绍最常用的两种
用户任务 (User Task)
具体来说就是需要手动执行的任务,即需要我们这变写完业务代码后,调用代码,来提交当前任务,当前任务才会被完成,从而走到下一个流程
taskService.complete(taskId, variables);
系统任务(Service Task)
系统自动完成的任务,而结合springboot 也就是在springboot写好的执行流程,自动执行完成后走到下一个流程。
网关
分为这么几类,会根据我们传入的流程变量及设定的条件走
- 排他网关(exclusive gateway)
这个网关只会走一个,我们走到这个网关时,会从上到下找第一个符合条件的任务往下走
- 并行网关(Parallel Gateway)
这个网关不需要设置条件,会走所有的任务
- 包含网关(Inclusive Gateway)
这个网关会走一个或者多个符合条件的任务
具体绘制方法
可以从左边直接拖过来,或者直接点击(具体自己尝试,很简单的)
开始
首先需要每个流程都需要有一个流程起点:
点击新建的流程点可以选择下一个节点是什么:
系统任务
系统任务推荐指定bean来实现java代码:
代码实现方法:
@Component
public class SignInDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
//执行的系统任务流程
}
@Bean("指定的bean")
public JavaDelegate signIn() {
return this::execute; // 返回当前类的 execute 方法
}
}
DelegateExecution
是Camunda BPM引擎提供的一个接口,用于在流程执行过程中传递上下文信息。它在流程实例执行的过程中充当了一个中心角色,提供了访问流程变量、流程定义、活动实例以及其他与流程执行相关的功能的方法。
补充:右边有个展开,点一下就出来了
设定网关
设定网关表达式:
在上一个系统任务中设置传入对应变量,让流程能顺利通过网关:
@Component
public class SignInDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
//执行的系统任务流程
// 设置流程变量,以至于能够顺利通过网关,如果没有设置的话会报错
execution.setVariable("通过", true);
}
@Bean("指定的bean")
public JavaDelegate signIn() {
return this::execute; // 返回当前类的 execute 方法
}
}
设定角色任务
在系统任务中指定对应的用户(受理人)来处理该事件:
@Component
public class SignInDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
//执行的系统任务流程
// 设置流程变量,以至于能够顺利通过网关,如果没有设置的话会报错
execution.setVariable("通过", true);
execution.setVariable("指定的角色", "用户id或者唯一的用户名称"); //指定受理人
}
@Bean("指定的bean")
public JavaDelegate signIn() {
return this::execute; // 返回当前类的 execute 方法
}
**注意:**Assignee只能是string类型,不能传入其他类型
完成角色任务
可以通过taskAssignee(“变量值(用户名或id)”) 来查找任务实例
可以通过task.setAssignee(“变量值(用户名或id)”);来修改当前实例的受理人
List<Task> tasks = taskService.createTaskQuery()
.processDefinitionKey(processDefinitionKey)
.taskAssignee(userId)
//这里两个参数意思是从第几行开始,一共需要几行
.listPage(pageNum, pageSize);
(如何获得当前节点任务实例ID的方法后面会讲)
通过某种方法获取到taskId(当前节点任务实例ID),通过这个id去查找任务,然后完成任务:
// 完成任务
@Override
public String submitApproval(String taskId, boolean approval,String note) {
// 获取任务
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null){
return "不存在该任务";
}
// 执行业务流程
// 设置审批结果
runtimeService.setVariable(task.getExecutionId(), "审批情况", approval); //task.getExecutionId()是实例id,设定全局变量能够走到结束流程
// 完成任务
taskService.complete(taskId);
return "审批已完成.";
}
设定processDefinitionKey
rocessDefinitionKey
是在使用Camunda BPM时的一个重要概念,它用于唯一标识一个流程定义。当您在Camunda Modeler中设计流程并通过BPMN 2.0标准定义了一个流程后,该流程会被赋予一个唯一的键值,这个键就是processDefinitionKey
。
什么是processDefinitionKey
?
processDefinitionKey
是在流程定义文件(通常是.bpmn
文件)中的属性,它用来唯一识别一个特定的流程定义。这个键通常对应于流程定义的ID,并且在流程定义部署到Camunda BPM引擎时会被使用。
在哪里定义?
在BPMN文件中,processDefinitionKey
是在<process>
元素上的id
属性。虽然这不是一个强制性的属性,但在实践中,为了能够通过代码引用流程定义,通常会为其指定一个有意义的id
。
例如,在BPMN文件中:
<process id="myProcess" name="My Process">
<!-- 流程节点定义 -->
</process>
在这个例子中,myProcess
就是processDefinitionKey
。
在绘制流程图,点击空白处就能看到processDefinitionKey,可以自己指定,设定,程序是通过指定的processDefinitionKey来启动对应流程图实例的。
基本概念
工作流基础变量名词解释
processDefinitionKey(默认流程Key)
解释:
processDefinitionKey
是一个用来唯一标识某个流程定义的字符串。当你使用Camunda Modeler设计并保存一个流程图时,这个流程图会有一个对应的processDefinitionKey
,它实际上就是流程定义文件中的<process>
标签的id
属性。用途:
当你需要在代码中启动一个流程实例时,就需要使用processDefinitionKey
来告诉Camunda BPM引擎你想启动哪一个流程定义。例如,如果你想启动名为orderApproval
的流程,就会使用orderApproval
作为processDefinitionKey
。
processInstanceId
(流程实例ID)
解释:
当你启动一个流程定义时,Camunda BPM引擎会为这个特定的流程实例生成一个唯一的processInstanceId
。这个ID用来唯一标识一个具体的流程实例,即使使用同一个流程定义启动多次,每次启动都会生成不同的processInstanceId
。用途:
使用processInstanceId
可以查询特定流程实例的状态,查看流程实例的历史记录,或者继续处理流程实例中的下一步。
nodeId
(节点ID)
解释:
在BPMN流程定义中,流程由一系列的活动(节点)组成,如开始事件、任务、网关等。每个活动都有一个唯一的标识符,即nodeId
。用途:
nodeId
用于标识流程中的各个活动。在流程执行过程中,可以用来追踪流程当前所处的位置,或者记录流程执行的历史轨迹。
taskId
(任务ID)
解释:
在流程定义中有许多任务需要用户完成,如审核任务、填写表单等。每个这样的任务都有一个唯一的taskId
。用途:
taskId
用于标识特定的任务实例,用户可以通过taskId
来查找和执行分配给他们的任务。
Assignee
(受理人)
解释:
在流程定义中,有些任务需要指定的用户来完成。Assignee
是指定给某个任务的执行者,即谁负责完成这项任务。用途:
Assignee
用于指派任务给具体的用户。只有被指派的用户才能看到任务并在任务列表中执行它。
BusinessKey
(业务Key)
解释:
BusinessKey
是用来关联业务对象与流程实例的标识符。它可以用来存储业务相关的信息,以便于后续的流程处理。用途:
使用BusinessKey
可以将业务数据关联到流程实例上,这样在流程执行过程中,可以方便地获取到业务相关的数据。比如说一个考勤流程,有人要申请考勤,那么就可以将这个人的唯一工作号码作为BusinessKey,方便查询和定位这个人的申请流程。
流程图讲解:
流程节点的类型及其意义
-
开始事件(Start Event):
- 意义:标志着流程的开始。可以是普通开始事件、定时器开始事件等。
- 用法:用于定义流程实例何时启动。例如,当接收到订单时,可以触发订单处理流程的开始事件。
-
结束事件(End Event):
- 意义:标志着流程或分支的结束。可以是普通结束事件、取消结束事件等。
- 用法:用于定义流程何时终止。例如,当订单处理完毕后,可以触发订单处理流程的结束事件。
-
任务(Task):
- 意义:表示需要完成的工作。可以是用户任务、服务任务等。
- 用法:用于定义需要执行的具体工作。例如,用户任务可能涉及人工审批,而服务任务则可以调用 Web 服务或执行脚本。
-
网关(Gateway):
- 独占网关(Exclusive Gateway):
- 意义:用于选择一条单一路径继续流程。
- 用法:根据条件选择下一个活动。例如,根据订单金额决定是否需要额外审批。
- 并行网关(Parallel Gateway):
- 意义:允许多条路径同时进行。
- 用法:同时执行多个并行任务。例如,同时发送邮件通知客户和更新库存系统。
- 复杂网关(Complex Gateway):
- 意义:用于更复杂的路由逻辑。
- 用法:处理更复杂的流程分支逻辑。
- 独占网关(Exclusive Gateway):
-
事件子流程(Event Subprocess):
- 意义:用于处理特定类型的事件。
- 用法:可以嵌套在流程中,等待特定事件的发生再执行。
-
序列流(Sequence Flow):
- 意义:连接两个节点,定义流程的流向。
- 用法:用于定义节点之间的顺序关系。
Services API
当然可以,下面是经过优化后的讲解,旨在让新手更容易理解Camunda引擎中的各个服务及其功能:
Camunda 服务概述
在使用Camunda BPM引擎时,有几个核心服务可以帮助我们管理和执行流程。以下是这些服务的基本介绍以及它们的主要用途:
RepositoryService
简介:RepositoryService是你与Camunda引擎交互的第一个切入点。它主要用于管理流程定义的部署,包括上传流程定义文件(如BPMN文件)到引擎中。
主要功能:
- 部署和管理流程定义。
- 查询已部署的流程定义和部署信息。
- 挂起和激活流程定义,控制其是否可以被启动。
- 检索流程定义中的文件和流程图。
RuntimeService
简介:RuntimeService是用于在流程执行期间与引擎交互的服务。它允许启动流程实例,并且可以查询正在执行的流程实例状态。
主要功能:
- 启动流程实例。
- 存储和检索流程实例的变量。
- 查询正在执行的流程实例和执行实例(指向流程实例当前位置的“令牌”)。
- 处理流程实例的外部触发。
TaskService
简介:TaskService专注于管理流程中的任务,特别是那些需要人为干预的任务。
主要功能:
- 查询分配给用户的任务。
- 创建新的任务,这些任务可以独立于任何流程实例。
- 分配任务给用户或组。
- 认领和完成任务。
IdentityService
简介:IdentityService提供了管理用户和组的功能,但请注意,核心引擎并不会在运行时验证用户身份。
主要功能:
- 创建、更新、删除和查询用户和组。
- 尽管可以将任务分配给任何用户,但实际的身份验证和授权需在应用层实现。
FormService
简介:FormService是可选的,它支持流程中的表单功能,比如启动流程前展示的表单或任务完成时所需的表单。
主要功能:
- 管理和渲染开始表单和任务表单。
- 表单数据与流程变量的交互。
HistoryService
简介:HistoryService提供了访问流程执行历史记录的功能。
主要功能:
- 查询流程实例的历史数据,如开始时间、执行用户、任务耗时等。
- 数据持久化级别可配置。
ManagementService
简介:ManagementService提供了对数据库表元数据的访问,并支持作业的查询和管理。
主要功能:
- 检索数据库表和元数据信息。
- 管理和查询作业,例如计时器作业。
FilterService
简介:FilterService允许创建和管理过滤器,用于简化常见的查询需求。
主要功能:
- 创建存储的查询,如任务查询。
- Tasklist应用使用过滤器来筛选任务。
ExternalTaskService
简介:ExternalTaskService专门处理外部任务,即在流程引擎之外执行的工作项。
主要功能:
- 提供对流程外部任务的访问和管理。
- 支持异步处理模式下的任务领取和完成。
Query API
简介:Camunda引擎提供了多种方式来查询数据。
主要功能:
- Java Queries:使用面向对象的API进行查询,适用于大多数场景。
- Native Queries:直接构建SQL查询语句,适用于复杂或特定的需求。
示例
下面是一个查询任务的简单示例:
// Java 查询示例
List<Task> tasks = taskService.createTaskQuery()
.taskAssignee("userOne")
.processVariableValueEquals("orderId", "8888")
.orderByDueDate().asc()
.list();
// Native 查询示例
List<Task> tasks = taskService.createNativeTaskQuery()
.sql("SELECT * FROM " + managementService.getTableName(Task.class) + " T WHERE T.NAME_ = #{taskName}")
.parameter("taskName", "aOpenTask")
.list();
Camunda 服务使用示例
进程过程中的变量数据
在Camunda BPM引擎中,流程实例变量(Process Instance Variables)是非常重要的概念,因为它们贯穿整个流程的生命周期,用于存储流程执行期间的数据。这些变量可以用来传递信息、控制流程逻辑、以及与其他系统集成。下面是一个关于流程变量从设置到使用的完整过程的讲解:
1. 定义变量
首先,在设计流程定义时,你需要考虑哪些数据需要在流程中传递。这些数据可以是输入参数、中间计算结果或者是输出结果。虽然在BPMN模型中没有直接定义变量的地方,但你可以通过流程节点的行为来隐式地定义变量。例如,你可以添加一个服务任务来设置初始变量。
2. 设置变量
一旦流程定义被部署,你就可以在启动流程实例时设置初始变量。这可以通过调用RuntimeService
的startProcessInstanceByKey
方法来完成,并且可以传入一个Map类型的参数来设置初始变量。
Map类型是<String,Object>,也就是可以将定义的对象都能传进去
Map<String, Object> variables = new HashMap<>();
variables.put("orderId", "12345");
User user = new User();
variables.put("User",user)
runtimeService.startProcessInstanceByKey("orderApproval", variables);
3. 查询变量
在流程执行过程中,你可能需要查询某些变量的值。这可以通过RuntimeService
提供的getVariable
或getVariables
方法来实现。
Object orderId = runtimeService.getVariable("processInstanceId", "orderId");
User user = (User) runtimeService.getVariable("processInstanceId", "User");
4. 修改变量
随着流程的推进,变量的值可能会发生变化。你可以通过服务任务中的脚本或服务调用来修改变量的值。修改变量可以通过setVariable
或setVariables
方法来完成。
runtimeService.setVariable("processInstanceId", "status", "approved");
5. 传递变量
变量不仅可以存储在流程实例中,还可以在流程节点之间传递。例如,当一个任务完成后,任务的结果可以作为变量传递给下一个任务或网关。
taskService.complete(taskId, variables);
6. 使用变量控制流程逻辑
流程中的某些决策点(如排他网关)可以根据变量的值来决定流程走向。例如,如果一个订单的金额超过一定阈值,则需要高级经理审批。
<exclusiveGateway id="approvalGateway">
<conditionExpression xsi:type="tFormalExpression"
evaluatesToType="string">${amount > 1000}</conditionExpression>
</exclusiveGateway>
7. 变量的作用域
需要注意的是,流程变量有不同的作用域,包括流程实例级、执行级(如子流程)和任务级。不同作用域的变量可以在不同的上下文中访问。
8. 清理变量
当流程实例结束时,与之相关的变量也将不再可用。如果你需要长期存储某些数据,应该将其持久化到数据库或其他存储系统中。
示例场景
假设有一个订单审批流程,需要根据订单金额来决定审批流程。订单金额作为一个变量在流程开始时被设置,并在审批过程中被多个节点使用。
// 设置订单金额
Map<String, Object> variables = new HashMap<>();
variables.put("orderAmount", 1500);
// 启动流程实例
runtimeService.startProcessInstanceByKey("orderApproval", variables);
// 某个服务任务检查订单金额并修改状态
runtimeService.setVariable("processInstanceId", "approvalStatus", "pending");
// 用户完成任务时提交结果
Map<String, Object> completionVariables = new HashMap<>();
completionVariables.put("reviewResult", "approved");
taskService.complete(taskId, completionVariables);
通过变量查询任务
通过变量来查询任务或流程实例是Camunda BPM引擎中一个非常实用的功能。这使得开发者可以根据业务逻辑中的条件来动态查询流程的状态。以下是详细的步骤和示例,说明如何使用变量来查询任务或流程实例。
查询任务
假设你想要找到所有分配给了特定用户并且订单ID等于某特定值的任务,可以使用TaskService
来执行这样的查询。
// 使用变量查询任务
List<Task> tasks = taskService.createTaskQuery()
.taskAssignee("johnDoe") // 指定任务的分配者
.processVariableValueEquals("orderId", "12345") // 使用变量值来过滤任务
.list();
for (Task task : tasks) {
System.out.println("Task ID: " + task.getId() + ", Name: " + task.getName());
}
在这个例子中,taskAssignee
方法用来过滤分配给特定用户johnDoe
的任务,而processVariableValueEquals
方法则是根据流程实例中的变量orderId
的值来进一步筛选任务。
查询流程实例
如果你需要根据变量来查询流程实例,可以使用RuntimeService
来进行查询。例如,找出所有订单ID为特定值的流程实例。
// 使用变量查询流程实例
List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery()
.variableValueEquals("orderId", "12345") // 使用变量值来过滤流程实例
.list();
for (ProcessInstance instance : processInstances) {
System.out.println("Process Instance ID: " + instance.getId() + ", Business Key: " + instance.getBusinessKey());
}
在这个例子中,variableValueEquals
方法用来根据变量orderId
的值来过滤流程实例。createProcessInstanceQuery
方法创建了一个流程实例查询对象,然后通过这个对象可以指定查询条件。
更复杂的查询
如果你需要更复杂的查询条件,比如组合条件(AND/OR)、范围查询等,可以使用多个查询方法来组合条件。例如,你可以根据两个变量来查询任务:
List<Task> tasks = taskService.createTaskQuery()
.taskAssignee("johnDoe")
.processVariableValueEquals("orderId", "12345")
.processVariableValueGreaterThan("amount", 1000)
.list();
在这里,我们不仅根据orderId
查询,而且还添加了一个额外的条件amount
大于1000。
查询单一实例或任务
如果你只想获取单个结果而不是列表,可以使用singleResult
方法代替list
:
Task singleTask = taskService.createTaskQuery()
.taskAssignee("johnDoe")
.processVariableValueEquals("orderId", "12345")
.singleResult();
if (singleTask != null) {
System.out.println("Found task: " + singleTask.getName());
} else {
System.out.println("No task found.");
}。
RepositoryService部署流程图
部署对象
// 创建部署对象
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource(requestParam.getResourcePath()) // 添加资源路径
.name(requestParam.getBpmnName()) // 设置部署名称
.deploy(); // 部署流程定义
部署位置是相对于资源路径来说,比如:BPMN/名称.bpmn
在web中就可以看到部署的实例了:
删除部署对象
// 删除部署,默认情况下不会级联删除流程实例和Job
repositoryService.deleteDeployment(deploymentId);// deploymentId = deploy.getId()
获取流程实例
@Override
public String getBpmnModelInstance(String processDefinitionId) {
// 获取流程模型实例
BpmnModelInstance bpmnModelInstance = repositoryService.getBpmnModelInstance(processDefinitionId);
if (ObjectUtil.isNotNull(bpmnModelInstance)) {
// 获取模型中的所有用户任务
Collection<UserTask> userTasks = bpmnModelInstance.getModelElementsByType(UserTask.class);
// 获取模型定义
Definitions definitions = bpmnModelInstance.getDefinitions();
// 日志输出
log.info("获取到流程模型实例:{}", bpmnModelInstance);
}
return null; // 返回提示信息,这里暂时返回null
}
runtimeService开启流程实例
启动流程实例
Map<String, Object> paramMap = request.getVariables();
// businessKey用于查询用户对应业务的待办任务
org.camunda.bpm.engine.runtime.ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, request.getBusinessKey(), paramMap);
使用RuntimeService
来启动一个新的流程实例,并传递业务键(businessKey
)和流程变量(paramMap
)。
拒绝流程实例
@Override
public String rejectProcessInstance(RejectInstanceRequest request) {
String processInstanceId = request.getProcessInstanceId();
ActivityInstance activity = runtimeService.getActivityInstance(processInstanceId);
runtimeService.createProcessInstanceModification(processInstanceId)
.cancelActivityInstance(activity.getId())
.setAnnotation("驳回")
.startBeforeActivity(request.getTargetNodeId())
.execute();
return "驳回成功";
}
使用RuntimeService
来拒绝(即回退)一个流程实例,并将流程重定向到指定的活动节点。
.cancelActivityInstance(activity.getId())
:取消当前活动实例。.setAnnotation("驳回")
:设置注释,用于标记此次操作的原因。.startBeforeActivity(request.getTargetNodeId())
:将流程实例重定向到指定的目标节点。.execute()
:执行流程实例修改操作。
挂起实例
挂起流程实例是指暂停特定流程实例的执行,使其不能继续前进。你可以选择挂起单个流程实例,也可以挂起一组符合特定条件的流程实例。
/**
* 挂起流程定义
*
* @param processDefinitionId 流程定义ID
* @return 提示信息
*/
@Override
public String suspendProcessDefinitionById(String processDefinitionId) {
// 挂起流程定义
repositoryService.suspendProcessDefinitionById(processDefinitionId); //也可以通过processDefinitionKey来挂起实例
return "挂起成功";
}
TaskService 操作详解
讲解TaskService
中的“查询任务列表”和“完成任务”的操作。
查询任务列表
@Override
public List<Task> queryTasks(TaskQueryRequest request) {
// 获取查询参数
String assignee = request.getAssignee();
String candidateGroup = request.getCandidateGroup();
// 创建任务查询对象
TaskQuery taskQuery = taskService.createTaskQuery()
.taskAssignee(assignee) // 指定任务的分配者
// 执行查询并返回任务列表
List<Task> tasks = taskQuery.list();
return tasks;
}
完成任务
@Override
public String completeTask(CompleteTaskRequest request) {
// 获取任务ID和任务变量
String taskId = request.getTaskId();
Map<String, Object> taskVariables = request.getVariables();
// 完成任务,并传递任务变量
taskService.complete(taskId, taskVariables);
return "任务完成";
}
示例
假设你需要查询分配给特定用户,并完成其中一个任务:
public class TaskQueryRequest {
private String assignee;
public TaskQueryRequest(String assignee) {
this.assignee = assignee;
}
public String getAssignee() {
return assignee;
}
public String getCandidateGroup() {
return candidateGroup;
}
}
public class CompleteTaskRequest {
private String taskId;
private Map<String, Object> variables;
public CompleteTaskRequest(String taskId, Map<String, Object> variables) {
this.taskId = taskId;
this.variables = variables;
}
public String getTaskId() {
return taskId;
}
public Map<String, Object> getVariables() {
return variables;
}
}
// 假设请求对象如下:
TaskQueryRequest queryRequest = new TaskQueryRequest("johnDoe");
// 查询任务
List<Task> tasks = taskService.queryTasks(queryRequest);
// 假设需要完成第一个任务
if (!tasks.isEmpty()) {
Task task = tasks.get(0);
CompleteTaskRequest completeRequest = new CompleteTaskRequest(task.getId(), Collections.singletonMap("result", "completed")); // 这是自己定义的方法
// 完成任务
String result = taskService.completeTask(completeRequest);
System.out.println(result); // 输出 "任务完成"
}
文档md格式开源地址:springboot结合Camunda7简单快速入门教程文档
觉得写得不错的话,可以给个star(´・ω・`) 。
参考文章:
1.SpringBoot 优雅集成 Camunda 7以上 工作流引擎,保姆级教程!
2.Camunda修炼手册