使用 Activiti 内置 Eclipse 项目
Activiti 可以和多种 Java 企业级开发技术 (Spring,JPA), 动态开发语言 (groovy) 以及 Web Service 开发工具 (CXF) 结合使用。在 Actitivi 的安装目录中的 workspace 文件夹中包含了 Activiti 自身特性和与这些开发技术结合使用的 Eclipse 项目示例 (activiti-engine-examples、activiti-spring-examples、activiti-groovy-examples、activiti-jpa-examples、activiti-cxf-examples 等 Eclipse 项目 )。要使用这些示例项目,只需在 Eclipse 中使用”Import->Existing Projects into Workspace”从文件系统中导入这些项目即可。
activiti-engine-examples 项目中包含了使用 Activiti 大部分主要功能的示例代码,这些代码使用的流程定义信息都已经部署在项目使用的 H2 内存数据库中。流程的执行中产生的信息也都会使用持久化 API 存储在该 H2 内存数据库中。
使用 Activiti Eclipse 流程设计器设计 Activiti 流程定义
Activiti 使用标准的 BPMN2.0 流程定义文件来描述工作流的定义。BPMN2.0 流程定义文件是一个符合行业标准的 XML 格式的文件。在这个文件中包含了流程的流转序列,步骤节点以及各个节点上相关的用户,变量信息等流程元素。在 BPMN2.0 XML 流程定义文件中还包含了各个流程元素在定义中的显示位置等信息,从而可以以图形化的方式来显示或编辑流程定义文件。目前已经有多种 BPMN2.0 流程定义文件的可视化编辑器。Activiti 中提供了 2 种定义文件的可视化编辑器:Web Application 形式的 Activiti Modeler 和 Eclipse 插件形式的流程编辑器。Activiti Modeler 必须部署在 Web 应用服务器中才能通过 Web 浏览器来使用而 Eclipse 插件形式的编辑器可以在 Eclipse 中直接使用,更好的结合了 Activiti 的流程设计和程序编码。在 Activiti5.6 版之后,Activiti Modeler 已经不再包含在 Activiti 的下载中。本文使用 Eclipse 插件的流程设计工具来介绍 BPMN2.0 流程定义文件的使用。
在 Eclipse 项目中可以直接通过创建 Activiti Diagram 的形式来创建一个流程定义文件并在可视化编辑器中编辑。如果项目中已经存在 BPMN2.0 流程定义 XML 文件,双击该文件 Eclipse 插件会自动生成一个后缀为 .activiti 的流程可视化编译文件。双击该文件可在可视化流程编辑器中打开该流程。图 6 是在可视化编辑器中打开一个流程定义文件的截图。
图 6.Activiti 可视化流程编辑器
当流程定义文件设计完成后,可以使用以下的 API 代码获取 RepositoryService,并使用该服务将流程定义文件部署到 Activiti 流程引擎中 ( 本代码示例中流程定义文件名称为 FinancialReportProcess.bpmn20.xml):
清单 1. 部署 BPMN2.0 流程定义文件
// 获取 RepositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); // 使用 RepositoryService 部署流程定义 repositoryService.createDeployment().addClasspathResource(" FinancialReportProcess.bpmn20.xml").deploy();Activiti 基本编程
如图 1 所示 ,Activiti 的 Java 编程模型的核心是 ProcessEngine。所有其他 service 都必须从 ProcessEngine 对象获取 , 代码清单 2 展示了如何使用 Activiti Java API 获取 ProcessEngine 和其他 Service 对象。
清单 2. 使用 Activiti API 获得各种 Service 对象
// 使用默认配置文件获取 ProcessEngine 对象实例 ProcessEngine processEngine = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration(). buildProcessEngine(); // 通过 ProcessEngine 实例获得 RepositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); // 通过 ProcessEngine 实例获得 RuntimeService RuntimeService runtimeService = processEngine.getRuntimeService(); // 通过 ProcessEngine 实例获得 TaskService TaskService taskService = processEngine.getTaskService(); HistoryService historyService = processEngine.getHistoryService(); // 通过 ProcessEngine 实例获得 FormService FormService formService = processEngine.getFormService(); // 通过 ProcessEngine 实例获得 ManagementService ManagementService managementService = processEngine.getManagementService(); // 通过 ProcessEngine 实例获得 IdentityService IdentityService identityService = processEngine.getIdentityService();
当获得了这些 Service 对象后,就可以使用这些 Service 对象来完成各种 Activiti 流程引擎的操作。在实际应用中需要综合使用各种服务来部署流程定义,启动流程实例,领取、查询完成用户任务以及查询流程运行历史纪录等 Activiti 流程引擎的主要功能。代码清单 3 展示了如何使用 API 代码来完成这一系列操作。该示例代码使用的 BPMN2.0 流程定义文件可以在 activiti-engine-examples 示例 Eclipse 工程中获取,使用到的用户和用户组也已经在 demo 系统初始化时写入了 Activiti 的后端 H2 数据库。
清单 3. 使用 Activiti 的各种 Service 对象完成流程引擎的业务功能
// 获取 RepositoryService 和 RuntimeService 实例 RepositoryService repositoryService = processEngine.getRepositoryService(); RuntimeService runtimeService = processEngine.getRuntimeService(); // 使用 RepositoryService 部署流程定义 repositoryService.createDeployment().addClasspathResource(" FinancialReportProcess.bpmn20.xml").deploy(); // 使用 RuntimeService 创建一个流程的实例 String procId = runtimeService.startProcessInstanceByKey("financialReport").getId(); // 获取 TaskService 实例 TaskService taskService = processEngine.getTaskService(); // 使用 TaskService 获取指定用户组的 Task 列表并使用指定用户领取这些任务 List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("accountancy").list(); for (Task task : tasks) { System.out.println(" Following task is available for accountancy group: " + task.getName()); // claim it taskService.claim(task.getId(), "fozzie"); } // 使用 TaskService 获取指定用户的工作 Task 列表,并完成这些任务 tasks = taskService.createTaskQuery().taskAssignee("fozzie").list(); for (Task task : tasks) { System.out.println("Task for fozzie: " + task.getName()); // Complete the task taskService.complete(task.getId()); } System.out.println("Number of tasks for fozzie: " + taskService.createTaskQuery().taskAssignee("fozzie").count()); // 使用 HistoryService 来查询指定流程实例的状态 HistoryService historyService = processEngine.getHistoryService(); HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(procId). singleResult(); System.out.println("Process instance end time: " + historicProcessInstance.getEndTime());
清单 3 代码首先将流程定义文件 FinancialReportProcess.bpmn20.xml 部署到了 Activiti 引擎中 ( 这个流程是 activiti-engine-examples 示例项目中内置的一个示例流程。共包含了 2 个顺序任务。第一个任务是 Write monthly financial report ,关联的用户组为 accountancy ,第二个任务为 Verify monthly financial report,关联的用户组为 management)。之后使用 RuntimeService 创建了一个流程的实例。实例创建完成后示例代码使用 TaskService 查询出该流程实例涉及到的 accountancy 组的任务 , 并使用 accountancy 组中的用户 fozzie 来领取并完成了该项任务。最后使用 HistoryService 来查询了该流程的运行状态。