当前位置: 首页 > news >正文

Activiti(六)- 启动、挂起、激活,查询及删除流程实例

1、引言

Activiti作为一款轻量级、开源的工作流和业务流程管理(BPM)平台。流程实例(Process Instance) 是 Activiti 核心运行机制的重要组成部分,代表了一个具体的业务流程从启动到结束的整个生命周期,本文将介绍关于activiti中关于启动、挂起、激活,查询及删除流程实例的方式。

2、启动流程实例

Activiti提供了多种启动流程实例的方式,主要通过RuntimeService、ProcessRuntime等接口实现。

2.1、ProcessInstanceBuilder的使用

ProcessInstanceBuilder是Activiti提供的一种灵活的流程实例构建方式,采用建造者模式(Builder Pattern),可以链式调用设置各种参数。
2.1.1、基本使用如下:
@RestController
@RequestMapping("/process")
public class StartUpProcess {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @GetMapping(value = "/start")
    public AjaxResult startProcess() {
        List<String> assigneeList = new ArrayList<>();
        assigneeList.add("admin");
        ProcessInstance instance = runtimeService.createProcessInstanceBuilder()
                .processDefinitionKey("Test-Process") // 设置流程定义Key
                .variable("assigneeList", assigneeList) / 设置流程变量
                .start();

        // 调试:查询生成的任务
        List<Task> tasks = taskService.createTaskQuery()
                .processInstanceId(instance.getId())
                .list();
        tasks.forEach(task -> {
            System.out.println("任务ID: " + task.getId() + ", 处理人: " + task.getAssignee());
        });
        return AjaxResult.success("下发成功!");
    }
}
2.1.2、主要方法说明(见源码:ProcessInstanceBuilder
方法说明使用场景
processDefinitionKey(String processDefinitionKey);通过 流程定义Key 启动流程较为通用方式
processDefinitionId(String processDefinitionId);通过 流程定义ID 启动流程(精确匹配)明确知道流程定义的唯一ID时使用(
messageName(String messageName);通过 消息名称 启动流程(需配合消息启动事件)BPMN 中定义了 <startEvent activiti:messageName="***"> 时使用
name(String processInstanceName);设置流程实例的 显示名称(非业务标识).-
businessKey(String businessKey);设置流程实例的 业务键(用于业务关联)-
tenantId(String tenantId)指定 租户ID(多租户隔离)确保 tenantId 与流程定义的租户一致
variables(Map<String, Object> variables);设置 持久化变量(存入数据库)-
variable(String variableName, Object value);设置 持久化变量(存入数据库)-
transientVariables(Map<String, Object> transientVariables);设置 临时变量(不存库,仅启动阶段有效)-
transientVariable(String variableName, Object value);设置 临时变量(不存库,仅启动阶段有效)-
start();执行流程启动操作-

2.2、 startProcess系列方法(见源码:RuntimeService

2.2.1、按流程定义Key启动
    public void startProcess() {
		// 最基本方式 - 仅指定流程Key
		ProcessInstance instance1 = runtimeService.startProcessInstanceByKey("Test-Process");

		// 带业务Key启动
		ProcessInstance instance2 = runtimeService.startProcessInstanceByKey("Test-Process", "20250413");

		// 带变量启动
		Map<String, Object> variables = new HashMap<>();
		variables.put("assignee", "admin");
		ProcessInstance instance3 = runtimeService.startProcessInstanceByKey("Test-Process", variables);

		// 带业务Key和变量启动
		ProcessInstance instance4 = runtimeService.startProcessInstanceByKey("Test-Process", "20250413", variables);
	}
2.2.2、 按流程定义ID启动
    public void startProcess() {
		// 最基本方式 - 仅指定流程ID
		ProcessInstance instance1 = runtimeService.startProcessInstanceById("Test-Process:1:9da64eadfc0946d9ba70606");

		// 带业务Key启动
		ProcessInstance instance2 = runtimeService.startProcessInstanceById("Test-Process:1:9da64eadfc0946d9ba70606", "20250413");

		// 带变量启动
		Map<String, Object> variables = new HashMap<>();
		variables.put("assignee", "admin");
		ProcessInstance instance3 = runtimeService.startProcessInstanceById("Test-Process:1:9da64eadfc0946d9ba70606", variables);

		// 带业务Key和变量启动
		ProcessInstance instance4 = runtimeService.startProcessInstanceById("Test-Process:1:9da64eadfc0946d9ba70606", "20250413", variables);
	}
2.2.3、 按消息启动
    public void startProcess() {
		// 简单消息启动
		ProcessInstance instance1 = runtimeService.startProcessInstanceByMessage("MessageTask");
		// 带业务Key的消息启动
		ProcessInstance instance2 = runtimeService.startProcessInstanceByMessage("MessageTask", "20250413");
		// 带变量的消息启动
		Map<String, Object> variables = new HashMap<>();
		variables.put("MessageTask", "1000");
		ProcessInstance instance3 = runtimeService.startProcessInstanceByMessage("MessageTask", variables);
		// 带业务Key和变量的消息启动
		ProcessInstance instance4 = runtimeService.startProcessInstanceByMessage("MessageTask", "20250413", variables);
	}
2.2.4、多租户支持
对于多租户系统,可以使用带tenantId的方法:
public void startProcess() {
	// 按Key启动,指定租户
	ProcessInstance instance1 = runtimeService.startProcessInstanceByKeyAndTenantId(
    "Test-Process", "tenant1");

	// 按消息启动,指定租户
	ProcessInstance instance2 = runtimeService.startProcessInstanceByMessageAndTenantId(
    "MessageTask", "tenant1");
}

2.3、 ProcessRuntime的start()方法(见源码:ProcessRuntime、ProcessPayloadBuilder

2.3.1、基本使用示例:
public void startProcess() {
        List<String> assigneeList = new ArrayList<>();
        assigneeList.add("admin");
        // 带变量启动
        Map<String, Object> variables = new HashMap<>();
        variables.put("assigneeList", assigneeList);
        ProcessInstance instance = processRuntime.start(ProcessPayloadBuilder
                .start()
                .withProcessDefinitionKey("Test-Process")
                .withName("测试")
                .withBusinessKey("businessId")
                .withVariables(variables)
                .build());
}

3、挂起流程实例

3.1、挂起特定流程实例

3.1.1、通过runtimeService.suspendProcessInstanceById()实现
    public AjaxResult suspendProcess(){
        runtimeService.suspendProcessInstanceById("368079dd58c34189a5208c3db269cfa5");
        return AjaxResult.success();
    }
3.1.2、通过processRuntime.suspend()实现
public AjaxResult suspendProcess(){

  		processRuntime.suspend(ProcessPayloadBuilder.suspend("368079dd58c34189a5208c3db269cfa5"));
		// or
  		processRuntime.suspend(ProcessPayloadBuilder.suspend().withProcessInstanceId("368079dd58c34189a5208c3db269cfa5").build());
        return AjaxResult.success();
}

3.2、挂起整个流程定义的所有实例

3.2.1、通过RepositoryService.suspendProcessDefinitionByKey()的方式
    public AjaxResult suspendProcess(){
        // 挂起整个流程定义(包括所有实例)
        repositoryService.suspendProcessDefinitionByKey("Test-Process",
                true,  // 是否挂起所有实例
                null   // 暂停日期,null表示立即执行
        );
        return AjaxResult.success();
    }
3.2.2、通过RepositoryService.suspendProcessDefinitionByKey()的方式
    public AjaxResult suspendProcess(){
        // 挂起整个流程定义(包括所有实例)
        repositoryService.suspendProcessDefinitionById("Test-Process",
                true,  // 是否挂起所有实例
                null   // 暂停日期,null表示立即执行
        );
        return AjaxResult.success();
    }

4、激活流程实例

4.1、激活特定流程实例

4.1.1、通过runtimeService.activateProcessInstanceById()实现
    public AjaxResult activateProcess(){
        runtimeService.activateProcessInstanceById("368079dd58c34189a5208c3db269cfa5");
//        ACT_RU_TASK   ACT_RU_EXECUTION
        return AjaxResult.success();
    }
4.1.2、通过processRuntime.resume()实现
public AjaxResult activateProcess(){
	processRuntime.resume(ProcessPayloadBuilder.resume("368079dd58c34189a5208c3db269cfa5"));	
	// or
	processRuntime.resume(ProcessPayloadBuilder.resume().withProcessInstanceId("368079dd58c34189a5208c3db269cfa5").build());
//        ACT_RU_TASK   ACT_RU_EXECUTION
	return AjaxResult.success();
}

4.2、挂起整个流程定义的所有实例

4.2.1、通过RepositoryService.activateProcessDefinitionByKey()的方式
    public AjaxResult activateProcess(){
        repositoryService.activateProcessDefinitionByKey("Test-Process",
                true,  // 是否激活所有实例
                null   // 激活日期,null表示立即执行
        );
        return AjaxResult.success();
    }
4.2.2、通过RepositoryService.activateProcessDefinitionById()的方式
    public AjaxResult activateProcess(){
        repositoryService.activateProcessDefinitionById("Test-Process",
                true,  // 是否激活所有实例
                null   // 激活日期,null表示立即执行
        );
        return AjaxResult.success();
    }

5、查询流程实例

通过 RuntimeService 和 HistoryService 进行查询

5.1、查询运行时实例

5.1.1、基本使用实例:
    public AjaxResult queryInstance(){
        List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().list();

        for (ProcessInstance pd : list) {
            try {
                StringBuilder sb = new StringBuilder();
                for (Field field : pd.getClass().getDeclaredFields()) {
                    field.setAccessible(true);
                    sb.append(field.getName()).append("=").append(field.get(pd)).append(", ");
                }
                logger.info("反射字段值: {}", sb.toString());
            } catch (Exception e) {
                logger.error("反射读取失败", e);
            }
        }

        return AjaxResult.success();
    }
5.1.2、主要方法说明(见源码:ProcessInstanceQuery
分类方法说明示例
基础查询processInstanceId(String)按流程实例ID查询.processInstanceId(“123”)
processInstanceBusinessKey(String)按业务键查询.processInstanceBusinessKey(“ORDER_001”)
processDefinitionKey(String)按流程定义Key查询.processDefinitionKey(“leaveProcess”)
状态筛选suspended()查询已挂起的流程实例.suspended()
active()查询活跃的流程实例.active()
时间范围startedAfter(Date)查询指定时间之后启动的实例.startedAfter(new Date(startTime))
startedBefore(Date)查询指定时间之前启动的实例.startedBefore(new Date(endTime))
变量条件variableValueEquals(String, Object)查询变量等于特定值的实例.variableValueEquals(“status”, “approved”)
variableValueNotEquals(String, Object)查询变量不等于特定值的实例.variableValueNotEquals(“priority”, 1)
variableValueGreaterThan(String, Object)查询变量值大于特定值的实例.variableValueGreaterThan(“amount”, 1000)
排序方法orderByProcessInstanceId().desc()按实例ID降序排列.orderByProcessInstanceId().desc()
orderByProcessDefinitionKey().asc()按流程定义Key升序排列.orderByProcessDefinitionKey().asc()
分页/计数listPage(int firstResult, int maxResults)分页查询.listPage(0, 10) // 第1页,每页10条
count()计数查询.processDefinitionKey(“order”).count()
高级查询includeProcessVariables()结果包含流程变量.includeProcessVariables().list()
processInstanceTenantId(String)按租户ID查询.processInstanceTenantId(“tenant1”)
or()…endOr()逻辑OR条件组合.or().processDefinitionKey(“p1”).processDefinitionKey(“p2”).endOr()
实用场景involvedUser(String)查询用户参与的流程实例.involvedUser(“user1”).active()
startedBy(String)查询指定用户启动的实例.startedBy(“admin”)
withJobException()查询因作业异常失败的实例.withJobException()

5.2、查询历史实例

5.2.1、基本使用实例:
    public AjaxResult queryInstance(){

        List<HistoricProcessInstance> list1 = historyService.createHistoricProcessInstanceQuery().list();
        for (HistoricProcessInstance pd : list1) {
            try {
                StringBuilder sb = new StringBuilder();
                for (Field field : pd.getClass().getDeclaredFields()) {
                    field.setAccessible(true);
                    sb.append(field.getName()).append("=").append(field.get(pd)).append(", ");
                }
                logger.info("反射字段值: {}", sb.toString());
            } catch (Exception e) {
                logger.error("反射读取失败", e);
            }
        }
        return AjaxResult.success();
    }
5.1.2、主要方法说明(见源码:HistoricProcessInstanceQuery
分类方法说明示例
基础查询processInstanceId(String)按历史流程实例ID查询.processInstanceId(“123”)
processInstanceBusinessKey(String)按业务键查询.processInstanceBusinessKey(“ORDER_001”)
processDefinitionKey(String)按流程定义Key查询.processDefinitionKey(“leaveProcess”)
状态筛选finished()查询已完成的流程实例.finished()
unfinished()查询未完成的流程实例.unfinished()
deleted()查询已删除的流程实例.deleted()
notDeleted()查询未删除的流程实例.notDeleted()
时间范围startedAfter(Date)查询指定时间之后启动的实例.startedAfter(new Date(startTime))
startedBefore(Date)查询指定时间之前启动的实例.startedBefore(new Date(endTime))
finishedAfter(Date)查询指定时间之后完成的实例.finishedAfter(new Date(completionTime))
finishedBefore(Date)查询指定时间之前完成的实例.finishedBefore(new Date(completionTime))
变量条件variableValueEquals(String, Object)查询结束时有指定变量值的实例.variableValueEquals(“status”, “approved”)
variableValueNotEquals(String, Object)查询结束时变量值不等于指定值的实例.variableValueNotEquals(“priority”, 1)
variableValueGreaterThan(String, Object)查询结束时变量值大于指定值的实例.variableValueGreaterThan(“amount”, 1000)
variableValueLike(String, String)模糊匹配字符串变量值.variableValueLike(“comment”, “%urgent%”)
排序方法orderByProcessInstanceId().desc()按实例ID降序排列.orderByProcessInstanceId().desc()
orderByProcessInstanceStartTime().asc()按启动时间升序排列.orderByProcessInstanceStartTime().asc()
orderByProcessInstanceDuration().desc()按执行时长降序排列.orderByProcessInstanceDuration().desc()
分页/计数listPage(int firstResult, int maxResults)分页查询.listPage(0, 10) // 第1页,每页10条
count()计数查询.processDefinitionKey(“order”).count()
高级查询includeProcessVariables()结果包含流程变量.includeProcessVariables().list()
processInstanceTenantId(String)按租户ID查询.processInstanceTenantId(“tenant1”)
or()…endOr()逻辑OR条件组合.or().processDefinitionKey(“p1”).processDefinitionKey(“p2”).endOr()
withJobException()查询因作业异常失败的实例.withJobException()
实用场景involvedUser(String)查询用户参与的历史流程实例.involvedUser(“user1”)
startedBy(String)查询指定用户启动的实例.startedBy(“admin”)
superProcessInstanceId(String)查询子流程实例.superProcessInstanceId(“parentProcessId”)

6、删除流程实例

通过 RuntimeService 或 ProcessRuntime 进行删除

6.1、使用runtimeService.deleteProcessInstance(String processInstanceId, String deleteReason)

    public AjaxResult deleteInstance(){
        runtimeService.deleteProcessInstance("368079dd58c34189a5208c3db269cfa5","测试");
        return AjaxResult.success();
    }

6.2、使用processRuntime.delete(DeleteProcessPayload deleteProcessPayload)

public AjaxResult deleteInstance(){
      processRuntime.delete(ProcessPayloadBuilder.delete("368079dd58c34189a5208c3db269cfa5"));
      
		//or
      processRuntime.delete(ProcessPayloadBuilder.delete().withProcessInstanceId("368079dd58c34189a5208c3db269cfa5").build());
        return AjaxResult.success();
}

相关文章:

  • Why does Java‘s hashCode() in String use 31 as a multiplier?
  • AT_abc398_e [ABC398E] Tree Game 题解
  • LLM做逻辑推理题 - 三人贴纸条游戏
  • STM32 HAL实现DHT11采集温湿度
  • 大模型面经 | DeepSeek-R1中提到的思维链(Chain of Thought,CoT)是什么?
  • 如何通过Radius认证服务器实现虚拟云桌面安全登录认证:安当ASP身份认证系统解决方案
  • 鼎讯信通 便携式雷达信号模拟器:打造复杂电磁环境的“全能型选手”
  • 突破亚马逊壁垒,Web Unlocker API 助您轻松获取数据
  • 通过使用 include 语句加载并执行一个CMake脚本来引入第三方库
  • MySQL:事务隔离级别和一致性
  • 第十章 json操作
  • java实现加密解密
  • 01_JDBC
  • 集合 Collection、Map
  • Qt炫酷仪表盘
  • 计算机网络:流量控制与可靠传输机制
  • Streamlit 最新进展分析
  • C++蓝桥杯实训篇(四)
  • Excel VBA 运行时错误1004’:方法‘Open’作用于对象‘Workbooks’时失败 的解决方法
  • openwrt软路由配置4--文件共享
  • 供应商已“陷入困境”,美汽车行业致信特朗普政府
  • 神舟二十号任务完成最后一次全区合练,发射场做好发射前各项准备
  • 教育部增设29种本科新专业,首建战略急需专业超常设置机制
  • 王东杰:重审康有为的“大同世界”
  • 经济日报:“关税讹诈”拦不住中国制造升级
  • 王毅、董军将主持召开中印尼外长防长“2+2”对话机制首次部长级会议