首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Activiti 工作流引擎實戰(二):Java API 完整流程從部署到任務辦理

     編輯:Java 相關知識

前言

Activiti 作為輕量級 BPMN 2.0 工作流引擎,核心價值在於將業務流程圖形化定義與代碼邏輯解耦。本文通過完整代碼示例,演示從流程定義部署、實例啟動、任務查詢到辦理完成的全生命週期操作。

核心 Service 體系

Service核心職責關鍵表
RepositoryService流程定義部署、查詢、資源管理ACT_RE_*
RuntimeService流程實例啟動、變量管理、執行控制ACT_RU_*
TaskService用戶任務查詢、簽收、辦理、轉辦ACT_RU_TASK
HistoryService歷史數據查詢、審計追蹤ACT_HI_*
ManagementService引擎管理、作業執行器控制ACT_GE_*

完整流程演示:採購申請流程

1. 流程建模 (Activiti Designer)

  • 組件:StartEvent → UserTask(創建申請: zhangsan) → UserTask(部門審批: lisi) → UserTask(財務審批: wangwu) → EndEvent
  • 生成:purchasingflow.bpmn20.xml、purchasingflow.png
  • 流程定義 Key:purchasingflow

2. 流程部署

@Autowired
private ProcessEngine processEngine;

@Test
public void deployProcess() {
    RepositoryService repositoryService = processEngine.getRepositoryService();
    
    InputStream bpmnIn = this.getClass().getClassLoader()
        .getResourceAsStream("diagram/purchasingflow.bpmn20.xml");
    InputStream pngIn = this.getClass().getClassLoader()
        .getResourceAsStream("diagram/purchasingflow.png");

    Deployment deployment = repositoryService.createDeployment()
        .addInputStream("purchasingflow.bpmn20.xml", bpmnIn)
        .addInputStream("purchasingflow.png", pngIn)
        .deploy();

    System.out.println("部署ID: " + deployment.getId());
    System.out.println("部署時間: " + deployment.getDeploymentTime());
}

3. 查詢流程定義版本控制

@Test
public void queryProcessDefinition() {
    RepositoryService rs = processEngine.getRepositoryService();
    List<ProcessDefinition> list = rs.createProcessDefinitionQuery()
        .processDefinitionKey("purchasingflow")
        .orderByProcessDefinitionVersion().desc()
        .list();

    for (ProcessDefinition pd : list) {
        System.out.println("定義ID: " + pd.getId()); // purchasingflow:1:4, purchasingflow:2:7...
        System.out.println("版本: " + pd.getVersion());
        System.out.println("部署ID: " + pd.getDeploymentId());
    }
    // 結論:同 Key 多次部署生成多版本,啟動實例默認使用最新版本
}

4. 啟動流程實例

@Test
public void startProcessInstance() {
    RuntimeService rs = processEngine.getRuntimeService();
    ProcessInstance pi = rs.startProcessInstanceByKey("purchasingflow");
    
    System.out.println("實例ID: " + pi.getId());
    System.out.println("定義ID: " + pi.getProcessDefinitionId()); // 指向最新版本
}

5. 查詢待辦任務

@Test
public void queryTasks() {
    TaskService ts = processEngine.getTaskService();
    List<Task> tasks = ts.createTaskQuery()
        .taskAssignee("zhangsan") // 指定辦理人
        .orderByTaskCreateTime().asc()
        .list();

    for (Task task : tasks) {
        System.out.println("任務ID: " + task.getId());
        System.out.println("任務名: " + task.getName());
        System.out.println("流程定義ID: " + task.getProcessDefinitionId());
        System.out.println("任務Key: " + task.getTaskDefinitionKey());
    }
}

6. 辦理任務 (推動流程流轉)

@Test
public void completeTask() {
    TaskService ts = processEngine.getTaskService();
    String taskId = "402"; // 從查詢結果獲取
    
    // 可攜帶流程變量
    Map<String, Object> vars = new HashMap<>();
    vars.put("amount", 50000);
    vars.put("urgent", true);
    
    ts.complete(taskId, vars);
    System.out.println("任務 " + taskId + " 已辦理,流程流轉至下一節點");
}

7. 完整流程自動化測試

@Test
public void fullProcessTest() {
    // 部署
    deployProcess();
    
    // 啟動
    ProcessInstance pi = processEngine.getRuntimeService()
        .startProcessInstanceByKey("purchasingflow");
    
    // 模擬三級審批
    String[] assignees = {"zhangsan", "lisi", "wangwu"};
    for (String assignee : assignees) {
        Task task = processEngine.getTaskService()
            .createTaskQuery()
            .taskAssignee(assignee)
            .singleResult();
        
        assertNotNull("未找到 " + assignee + " 的待辦任務", task);
        processEngine.getTaskService().complete(task.getId());
        System.out.println(assignee + " 審批完成");
    }
    
    // 驗證流程結束
    ProcessInstance ended = processEngine.getRuntimeService()
        .createProcessInstanceQuery()
        .processInstanceId(pi.getId())
        .singleResult();
    assertNull("流程應已結束", ended);
}

進階實戰技巧

流程變量作用域管理

  • taskService.setVariableLocal(taskId, key, value):任務級局部變量
  • runtimeService.setVariable(executionId, key, value):流程實例級全局變量
  • 網關決策建議使用流程變量:${amount > 10000}

任務簽收與轉辦

// 簽收 (候選組/人場景)
taskService.claim(taskId, "lisi");

// 轉辦
taskService.setAssignee(taskId, "zhaoliu");

// 加簽 (動態添加審批人)
taskService.addCandidateUser(taskId, "extraApprover");

異常處理與補償

  • 邊界事件捕獲錯誤:errorEventDefinition
  • 補償處理器:compensateEventDefinition
  • 人工介入:管理員可通過 ManagementService 執行跳轉、終止等操作

總結

Activiti 核心 API 操作鏈:RepositoryService 部署 → RuntimeService 啟動 → TaskService 查詢/辦理 → 循環至結束。掌握版本控制、變量作用域、任務生命週期管理,是構建穩健工作流應用的關鍵。建議結合 Spring Boot Starter 整合,利用 @Transactional 保證流程操作與業務數據一致性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved