1 什么是流程实例?

  • 参与者(可以是用户也可以是程序)按照流程定义内容发起一个流程,这就是一个流程实例。是动态的。
  • 以下是流程定义和流程实例的图解:

流程定义和流程实例的图解.png

2 启动流程实例

  • 流程定义部署在Activiti中后,就可以在系统中通过Activiti去管理该流程的执行,执行流程表示流程的一次执行。比如部署系统请假流程后,如果某个用户要申请请假这个时候就需要执行这个流程,如果另外一个用户也要申请请假则也需要执行该流程,每个执行互不影响,每个执行是单独的流程实例。
  • 执行流程首先需要启动流程实例:
  1. package com.sunxiaping;
  2. import org.activiti.engine.ProcessEngine;
  3. import org.activiti.engine.ProcessEngineConfiguration;
  4. import org.activiti.engine.RuntimeService;
  5. import org.activiti.engine.runtime.ProcessInstance;
  6. import org.junit.Test;
  7. /**
  8. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  9. * @version 1.0
  10. * 2020-08-01 21:13
  11. */
  12. public class ActivitiStartProcessInstanceTest {
  13. /**
  14. * act_hi_actinst 活动实例
  15. * act_hi_identitylink 参与者信息
  16. * act_hi_procinst 流程实例
  17. * act_hi_taskinst 任务实例
  18. * act_ru_execution 执行表
  19. * act_ru_identitylink 参与者信息
  20. * act_ru_task 任务表
  21. */
  22. @Test
  23. public void test() {
  24. //创建ProcessEngineConfiguration对象
  25. ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
  26. ProcessEngine processEngine = configuration.buildProcessEngine();
  27. //获取RuntimeService对象
  28. RuntimeService runtimeService = processEngine.getRuntimeService();
  29. //根据流程定义的key启动流程实例
  30. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday");
  31. //获取流程实例的相关信息
  32. String processDefinitionId = processInstance.getProcessDefinitionId();
  33. System.out.println("流程定义的id = " + processDefinitionId);
  34. String deploymentId = processInstance.getDeploymentId();
  35. System.out.println("流程部署的id = " + deploymentId);
  36. String id = processInstance.getId();
  37. System.out.println("流程实例的id = " + id);
  38. String activityId = processInstance.getActivityId();
  39. System.out.println("当前活动的id = " + activityId);
  40. }
  41. }

3 BusinessKey(业务标识)

  • 启动流程实例时,指定的businessKey,就会在act_run_execution表中存储businessKey。
  • BusinessKey:业务标识,通常为业务表的主键,业务标识和流程实例一一对应。业务标识来源于业务系统。存储业务标识就是根据业务标识来关联查询业务系统的数据。比如:请假流程启动一个流程实例,就可以将请假单的id作为业务标识存储到Activiti中,将来查询Activiti的流程实例信息就可以获取请假单的id从而关联查询业务系统数据库得到请假单信息。
  • 示例:
  1. package com.sunxiaping;
  2. import org.activiti.engine.ProcessEngine;
  3. import org.activiti.engine.ProcessEngineConfiguration;
  4. import org.activiti.engine.RuntimeService;
  5. import org.activiti.engine.runtime.ProcessInstance;
  6. import org.junit.Test;
  7. /**
  8. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  9. * @version 1.0
  10. * 2020-08-01 21:13
  11. */
  12. public class ActivitiBusinessKeyTest {
  13. @Test
  14. public void test() {
  15. String processDefinitionKey = "holiday";
  16. String businessKey = "1";
  17. //创建ProcessEngineConfiguration对象
  18. ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
  19. ProcessEngine processEngine = configuration.buildProcessEngine();
  20. RuntimeService runtimeService = processEngine.getRuntimeService();
  21. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey);
  22. String businessKeyDb = processInstance.getBusinessKey();
  23. System.out.println("businessKeyDb = " + businessKeyDb);
  24. }
  25. }

4 查询流程实例(关联businessKey)

  • 需求:
    • 在Activiti实际应用时,查询流程实例列表时可能要显示出业务系统的一些相关信息,比如:查询当前运行的请假流程列表需要将请假单名称、请假天数等信息显示出来,请假天数等信息在业务系统中存在,而并没有在Activiti数据库中存在,所以是无法通过Activiti的API查询到请假天数等信息。
  • 实现:
    • 在查询流程实例的时候,通过businessKey(业务标识)关联查询业务系统的请假单表,查询出请假天数等信息。
    • 通过下面的代码就可以获取到Activiti中所对应实例保存的key。而这个业务key一般都会保存相关联的业务操作表的主键,再通过主键id去查询业务信息,比如通过请假单的id,去查询更多的请假信息(请假人、请假时间、请假天数、请假事由等)。
      1. String businessKeyDb = processInstance.getBusinessKey();

5 流程实例挂起和激活

5.1 概述

  • 某些情况可能由于流程变更需要将当前运行的流程暂停而不是直接删除,流程暂停后将不会继续执行。

5.2全部流程实例挂起和激活

  • 操作流程定义为挂起状态,该操作定义下面的所有的流程实例将全部暂停。
  • 流程定义为挂起状态,该流程定义下将不允许启动新的流程实例,同时该流程定义下的所有流程实例将全部挂起暂停执行。
  • 示例:
  1. package com.sunxiaping;
  2. import org.activiti.engine.ProcessEngine;
  3. import org.activiti.engine.ProcessEngineConfiguration;
  4. import org.activiti.engine.RepositoryService;
  5. import org.activiti.engine.repository.ProcessDefinition;
  6. import org.junit.Test;
  7. import java.util.List;
  8. /**
  9. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  10. * @version 1.0
  11. * 2020-08-03 20:02
  12. */
  13. public class ActivitiAllProcessSuspendActivateTest {
  14. @Test
  15. public void test() {
  16. //获取ProcessEngineConfiguration对象
  17. ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
  18. //获取ProcessEngine对象
  19. ProcessEngine processEngine = configuration.buildProcessEngine();
  20. //获取RepositoryService对象
  21. RepositoryService repositoryService = processEngine.getRepositoryService();
  22. //获取指定key的流程定义
  23. List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery().processDefinitionKey("holiday").list();
  24. for (ProcessDefinition processDefinition : processDefinitionList) {
  25. //如果该流程定义是暂停的
  26. boolean suspended = processDefinition.isSuspended();
  27. if (suspended) {
  28. //如果该流程定义是暂停的,则激活该流程定义下的所有流程实例
  29. //第一个参数,表示流程定义的id
  30. //第二个参数,表示是否级联激活该流程定义的流程实例
  31. //第三个参数,表示激活这个流程定义的时间,如果不填写,从此刻开始
  32. repositoryService.activateProcessDefinitionById(processDefinition.getId(), true, null);
  33. System.out.println("流程定义" + processDefinition.getId() + "激活");
  34. } else {
  35. //如果该流程定义是激活的,则挂起该流程定义
  36. repositoryService.suspendProcessDefinitionById(processDefinition.getId(), true, null);
  37. System.out.println("流程定义" + processDefinition.getId() + "挂起");
  38. }
  39. }
  40. }
  41. }

单个流程实例挂起,流程实例不能执行异常.jpg

5.3 单个流程实例挂起和激活

  • 操作流程实例对象,针对单个流程执行挂起操作,某个流程实例挂起则此流程不再执行,完成该流程实例的当前任务将报异常。
  • 示例:
  1. package com.sunxiaping;
  2. import org.activiti.engine.ProcessEngine;
  3. import org.activiti.engine.ProcessEngineConfiguration;
  4. import org.activiti.engine.RuntimeService;
  5. import org.activiti.engine.runtime.ProcessInstance;
  6. import org.junit.Test;
  7. import java.util.List;
  8. /**
  9. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  10. * @version 1.0
  11. * 2020-08-03 20:02
  12. */
  13. public class ActivitiSingleProcessSuspendActivateTest {
  14. @Test
  15. public void test() {
  16. String processInstanceId = "2501";
  17. //获取ProcessEngineConfiguration对象
  18. ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
  19. //获取ProcessEngine对象
  20. ProcessEngine processEngine = configuration.buildProcessEngine();
  21. RuntimeService runtimeService = processEngine.getRuntimeService();
  22. List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).list();
  23. for (ProcessInstance processInstance : processInstanceList) {
  24. boolean suspended = processInstance.isSuspended();
  25. if (suspended) {
  26. runtimeService.activateProcessInstanceById(processInstance.getProcessInstanceId());
  27. System.out.println("流程实例" + processInstance.getProcessDefinitionId() + "激活");
  28. } else {
  29. runtimeService.suspendProcessInstanceById(processInstance.getProcessInstanceId());
  30. System.out.println("流程实例" + processInstance.getProcessDefinitionId() + "挂起");
  31. }
  32. }
  33. }
  34. }

单个流程实例挂起,流程实例不能执行异常.jpg