Activiti 流程
流程引擎
流程启动,运行的具体环境。
创建流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
创建流程引擎时,会在classpath下搜索activiti.cfg.xml配置文件,并基于此文件进行构建。
如果没有查询到配置文件,则会基于默认配置创建引擎。
可以通过编程的方式实现引擎配置。
配置内容包括: 数据库, 是否启用Job执行器,邮件服务器,历史存储,缓存配置,日志,事件监听等。
流程引擎的服务
// 创建引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 从引擎中获取各类服务
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
ManagementService managementService = processEngine.getManagementService();
IdentityService identityService = processEngine.getIdentityService();
HistoryService historyService = processEngine.getHistoryService();
FormService formService = processEngine.getFormService();
所有的服务都是无状态的。
Repository Service 提供了管理和控制发布包和流程的定义操作。如:部署流程定义;查询引擎中的已有发布包和流程定义;暂停或激活发布包;获取发布包中的资源,如xml文件或是流程图片等。
Runtime Service 负责启动一个流程顶的新实例。对于每个流程定义来说,同一个时间内,可以有多个实例在执行。runtime service还可以用于获取和保存流程实例中的变量。或是用于查询流程实例,执行实例,触发实例等。
Task Service 任务相关的服务。包含功能:查询分配给用户或用户组的任务的信息;创建独立运行于流程实例外的任务;手段设置任务与用户的关联关系;认领(claim)任务, 完成(complete)任务等。
Identity Service 负责管理(创建,更新,删除,查询...)群组和用户。注意,activiti执行时不会对用户执行检查。任务可以分配给任何人,无论这个用户是否存在。
Form Service 表单服务。可选的。提供启动表单和任务表单两个概念。即在流程实例启动前展示给用户的,和完成任务时展示给用户的两种表单。注意,这是个可选服务,表单不一定需要嵌入到流程定义中。
History Service 历史数据服务。执行流程时,引擎会保存如实例启动时间,任务参与者,完成时间,执行路径等数据。Histroy Service通过查询功能获取这些数据。
Management Service 管理服务。提供查询和管理异步操作的功能。异步操作的用途包含定时器,延迟,暂停,激活等。
流程定义
流程定义的发布
编写bpmn的xml文件,并通过使用Repository Service进行发布。
示例: 某个请假流程的定义xml
${employeeName} would like to take ${numberOfDays} day(s) of vacation (Motivation: ${vacationMotivation}).
management
${vacationApproved == 'true'}
${vacationApproved == 'false'}
Your manager has disapproved your vacation request for ${numberOfDays} days.
Reason: ${managerMotivation}
${employeeName}
${resendRequest == 'true'}
${resendRequest == 'false'}
xml对应的流程图
流程的部署
repositoryService.createDeployment()
.name("my-process-name")
.addClasspathResource("org/activiti/myProcess.bpmn20.xml")
.addClasspathResource("org/activiti/myProcess.png")
.deploy();
如果发布使用的是bpmn文件,则改为addClassResource("org/activiti/myProcess.bpmn")即可。
使用这种方式时,没有提供流程图片文件。因此可以通过配置流程引擎自动生成图片。
...
通过API获取流程定义的图片资源
ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("yourProcessId").singleResult();
String diagramResourceName = procDef.getDiagramResourceName();
InputStream imageStream =
repositoryService.getResourceAsStream(procDef.getDeploymentId(), diagramResourceName);
流程定义的挂起与激活
// 挂起流程。流程将无法新建实例,继续执行,异步操作。
repositoryService.suspendProcessDefinitionByKey("vacationRequest");
try {
runtimeService.startProcessInstanceByKey("vacationRequest");
} catch (ActivitiException e) {
e.printStackTrace(); // 无法再启动该定义流程的实例
}
// 重新激活流程
repositoryService.activateProcessDefinitionByKey("vacationRequest");
流程实例
流程实例都共享一个流程定义。
在启动流程实例之前,必须保证流程定义已经被发布。然后通过流程定义的ID启动实例。(在流程模型中定义的ID,在activiti中对应于key。如流程id,任务id等)
ProcessInstance proInst = runtimeService.startProcessInstanceByKey("yourProcessId");
创建一个流程实例,首先会进入开始事件。
在开始事件之后,它会沿着所有的外出连线执行,到达第一个任务。Activiti会把一个任务保存到数据库中。这时,分配到这个任务的用户或群组会被解析,也会保存到数据库里。
Activiti引擎会继续执行流程环节,直至遇到一个等待状态,如用户任务等。在等待状态下,当前的流程实例的状态会保存到数据库中。直至用户决定完成任务才能改变这个状态。
之后引擎会继续执行,直至遇到下一个等待状态,或是流程结束。
在引擎运行过程中,如果出现重启或是崩溃情况,流程状态也会安全的保存在数据库中。
流程的启动
流程定义发布到引擎后,就可以基于它发起新的流程实例。如先前所说,基于同一个流程定义可以同时存在多个流程实例。
// 表单元素
Map variables = new HashMap();
variables.put("employeeName", "Kermit");
variables.put("numberOfDays", new Integer(4));
variables.put("vacationMotivation", "I'm really tired!");
// 使用RuntimeService获得与流程运行相关的信息
RuntimeService runtimeService = processEngine.getRuntimeService();
// 从流程引擎中查找一个定义为"vacationRequest"的流程并启动
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("vacationRequest", variables);
// Verify that we started a new process instance
Log.info("Number of process instances: " + runtimeService.createProcessInstanceQuery().count());
流程中的任务的完成
// Fetch all tasks for the management group
TaskService taskService = processEngine.getTaskService();
// 查找当前未完成的且执行用户组是management的任务
List tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
for (Task task : tasks) {
Log.info("Task available: " + task.getName());
}
// 此处应获取到任务: adjustVacationRequestTask
Task task = tasks.get(0);
Map taskVariables = new HashMap();
taskVariables.put("vacationApproved", "false"); //拒绝了请假
taskVariables.put("managerMotivation", "We have a tight deadline!");
// 任务完成。流程进入到下一个步骤
taskService.complete(task.getId(), taskVariables);
// !!如何需要获取流程中的变量
runtimeService.getVariables(processInstanceId);