文章目录
- 概念
- [流程部署 Deployment](#流程部署 Deployment)
- [Runtime / Task(Services)](#Runtime / Task(Services))
概念
建议先阅读:
bash
Activiti 7 的真实分工是:
BPMN 文件(定义)
↓
Process Engine(解释 + 执行)
↓
数据库(状态持久化)
也就是说:BPMN 只是 定义,真正"跑流程"的,是 Process Engine,Activiti 提供了一组服务,用于访问和操作流程实例、任务以及历史数据。
bash
┌──────────────────────────┐
│ Runtime API │ ← 流程实例在"跑"
├──────────────────────────┤
│ Task API │ ← 人在"办事"
├──────────────────────────┤
│ History API │ ← 已发生的事实
└──────────────────────────┘
所以流程引擎本质上是一个:"BPMN 状态机 + 持久化调度器",流程引擎负责执行 BPMN 2.0 流程定义,并管理流程实例的状态。
流程实例表示一次流程定义的执行。
在java中可以这样理解:
bash
你可以这样类比:
BPMN 概念 Java 类比
Process Definition class
Process Instance new class()
Engine 内部真正跑的是:Execution,Execution 表示在流程中移动的一个令牌(token)。
Execution = 引擎眼里的"当前路径",一个流程实例可以包含多个执行路径(execution)。ProcessInstance 是"整体流程",Execution 是"正在走的路线"。
流程部署 Deployment
在流程被执行之前,必须先将其部署到 Activiti 引擎中。
整体流程:
bash
BPMN 文件
↓(Deployment)
Process Definition
↓(RuntimeService)
Process Instance
↓
Execution / Task
RepositoryService 用于管理流程部署和流程定义。
部署:
java
@RestController
@RequiredArgsConstructor
public class ActivityDemoController {
private final RepositoryService repositoryService;
@PostMapping("/deploy")
public void testDeploy(@RequestParam("bpmnFile")MultipartFile bpmnFile,String bpmnName) {
try {
repositoryService
.createDeployment()
.name(bpmnName)
.addInputStream(bpmnFile.getOriginalFilename(), bpmnFile.getInputStream())
.deploy();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
这个会影响3个表:
act_re_deployment:存放部署记录
act_re_procdef:存放流程定义
act_ge_bytearray:存放二进制文件
当部署的bpmn的文件中共的process_id 相同的时候就会act_re_procdef中新加一条记录(其他表也会新增一条记录),但是version + 1
Runtime / Task(Services)
Activiti 提供不同的服务,用于管理运行时数据、任务数据以及历史数据。
Runtime
启动流程:
java
/**
* 开启流程
*/
@PostMapping("/startProcess")
public void startProcess(String processKey) {
/**
* 可以设置流程发起人,也可以不设置
*/
Authentication.setAuthenticatedUserId("流程发起人1");
//流程业务key,可以理解为本次启动流程实例的名字
String businessKey = processKey + DateTimeFormatter.ofPattern("yyyyMMddhhmmssSSS").format(LocalDateTime.now());
// 设置「全局字段」(流程变量)
HashMap<String, Object> globalValue = new HashMap<>();
globalValue.put("HrCode", "123456");
/**
* 1. 根据 KEY_ 找到最新版本的 ProcessDefinition
* 2. 创建 ProcessInstance
* 3. 创建 root Execution
* 4. 按 BPMN 顺序推进
* 5. 碰到 endEvent → 流程结束
*/
runtimeService.startProcessInstanceByKey(processKey,businessKey,globalValue);
//当然也可以自定义启动版本,但是要指定流程定义id
//runtimeService.startProcessInstanceById("processDefinitionId");
}
每个流程实例都会创建一个根 execution。
当流程到达一个等待状态(例如 UserTask)时,会创建一个子 execution。
Task
一个 UserTask = root execution + 一个等待态 child execution
两条 ACT_ID_ 一样
但只有一条能关联到 Task
java
/**
* 完成任务
*/
@GetMapping("/completeTask")
public void completeTask(String taskId) {
/**
* 任务结束前可以设置流程作用域变量
*/
Map<String, Object> exeMap = new HashMap<>();
exeMap.put("我是流程作用域变量", "程作用域变量值");
taskService.setVariables(taskId, exeMap);
/**
* 任务结束前可以设置当前任务作用域变量
* 一般只用于"本任务结束瞬间"的流程决策
*/
Map<String, Object> curTaskMap = new HashMap<>();
curTaskMap.put("我是hr任务作用域变量","hr任务变量值");
taskService.setVariablesLocal(taskId, curTaskMap);
taskService.complete(taskId);
}