上一篇介绍了activiti,以及一个简单的demo。估计很多刚接触activiti的小伙伴还是迷迷糊糊的,这篇会详细介绍activiti API相信看完之后会为你解决之前的困惑。
引擎API是与Activiti打交道的最常用方式。 从ProcessEngine中,你可以获得很多囊括工作流/BPM方法的服务。 ProcessEngine和服务类都是线程安全的。 你可以在整个服务器中仅保持它们的一个引用就可以了。
上图将avtiviti API的关系 一目了然的展现再我们面前,比如上一篇的demo是将他们所有的api注入进来,实际上只需要注入ProcessEngine就可以的,它的其他的子API都可以通过get方法获取
如下
@Autowired
ProcessEngine processEngine;
@Test
public void test1(){
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
RepositoryService repositoryService = processEngine.getRepositoryService();
....
}
知道了它API对应的关系,接下来是各个API的作用:以下描述参考官方文档
1. ProcessEngines: 会扫描所有activiti.cfg.xml 和 activiti-context.xml 文件。 对于activiti.cfg.xml文件,流程引擎会使用Activiti的经典方式构建: ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine(). 对于activiti-context.xml文件,流程引擎会使用Spring方法构建:先创建一个Spring的环境, 然后通过环境获得流程引擎。
2. RepositoryService: 可能是使用Activiti引擎时最先接触的服务。 它提供了管理和控制发布包和流程定义的操作。 这里不涉及太多细节,流程定义是BPMN 2.0流程的java实现。 它包含了一个流程每个环节的结构和行为。 发布包是Activiti引擎的打包单位。一个发布包可以包含多个BPMN 2.0 xml文件和其他资源。 开发者可以自由选择把任意资源包含到发布包中。 既可以把一个单独的BPMN 2.0 xml文件放到发布包里,也可以把整个流程和相关资源都放在一起。 (比如,'hr-processes'实例可以包含hr流程相关的任何资源)。 可以通过RepositoryService来部署这种发布包。 发布一个发布包,意味着把它上传到引擎中,所有流程都会在保存进数据库之前分析解析好。 从这点来说,系统知道这个发布包的存在,发布包中包含的流程就已经可以启动了。
3. RuntimeService:它负责启动一个流程定义的新实例。 如上所述,流程定义定义了流程各个节点的结构和行为。 流程实例就是这样一个流程定义的实例。对每个流程定义来说,同一时间会有很多实例在执行。 RuntimeService也可以用来获取和保存流程变量。 这些数据是特定于某个流程实例的,并会被很多流程中的节点使用 (比如,一个排他网关常常使用流程变量来决定选择哪条路径继续流程)。 Runtimeservice也能查询流程实例和执行。 执行对应BPMN 2.0中的'token'。基本上执行指向流程实例当前在哪里。 最后,RuntimeService可以在流程实例等待外部触发时使用,这时可以用来继续流程实例。 流程实例可以有很多暂停状态,而服务提供了多种方法来'触发'实例, 接受外部触发后,流程实例就会继续向下执行。
4. TaskService:它是Activiti这类BPMN引擎的核心功能之一。 所有与任务有关的功能都包含在TaskService中:
·查询分配给用户或组的任务
·创建独立运行任务。这些任务与流程实例无关。
·手工设置任务的执行者,或者这些用户通过何种方式与任务关联。
·认领并完成一个任务。认领意味着一个人期望成为任务的执行者, 即这个用户会完成这个任务。完成意味着“做这个任务要求的事情”。 通常来说会有很多种处理形式。
5. IdentityService:它可以管理(创建,更新,删除,查询...)群组和用户。 请注意, Activiti执行时并没有对用户进行检查。 例如,任务可以分配给任何人,但是引擎不会校验系统中是否存在这个用户。 这是Activiti引擎也可以使用外部服务,比如ldap,活动目录,等等。
6. FormService: 它是一个可选服务。即使不使用它,Activiti也可以完美运行, 不会损失任何功能。这个服务提供了启动表单和任务表单两个概念。 启动表单会在流程实例启动之前展示给用户, 任务表单会在用户完成任务时展示。Activiti支持在BPMN 2.0流程定义中设置这些表单。 这个服务以一种简单的方式将数据暴露出来。再次重申,它时可选的, 表单也不一定要嵌入到流程定义中。
7. HistoryService :它提供了Activiti引擎手机的所有历史数据。 在执行流程时,引擎会保存很多数据(根据配置),比如流程实例启动时间,任务的参与者, 完成任务的时间,每个流程实例的执行路径,等等。 这个服务主要通过查询功能来获得这些数据。
8. ManagementService:在使用Activiti的定制环境中基本上不会用到。 它可以查询数据库的表和表的元数据。另外,它提供了查询和管理异步操作的功能。 Activiti的异步操作用途很多,比如定时器,异步操作, 延迟暂停、激活,等等。后续,会讨论这些功能的更多细节。
官方文档这东西看多了发困,主要是脑袋对它没有一个清晰的轮廓,下面来点带你提神的。
完成一个简单的流程,你可以把它分成几步:
1,画流程图
2,创建流程实例
3,启动流程实例
4,得到代办
5,审批并提交
6,完成流程
完了,一个简单的流程就这些,再给一页代码,你应该就一目了然了(其中 findMyPersonTask() 和 completeTask() 可以提取一下重复使用,我这里为了看着方便就没提取)
package com.uniware.activity;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiDemoTest {
@Autowired
ProcessEngine processEngine;
/**
*这里注意:
* 创建流程实例,可以在config中创建,这样项目启动时就将流程实例创建好,后面要用直接启动对应的流程实例就行。
*/
@Test
public void delployFlow() {
System.out.println("--------创建流程实例---------");
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.name("请假流程")
.addClasspathResource("diagrams/demo.bpmn")//z合理是你画的流程图
.deploy();
System.out.println("部署ID:" + deployment.getId());
System.out.println("部署名称:" + deployment.getName());
}
@Test
public void flowStart() {
System.out.println("-----------启动流程-----------");
RuntimeService runtimeService = processEngine.getRuntimeService();
Map map = new HashMap();
map.put("pm", "刘二狗i");//注意这里,对应我们流程图的${pm}
map.put("day",3);//这里对应流程图${day}
//这个是流程实例的key,就是整个流程图的id
ProcessInstance pi = runtimeService.startProcessInstanceByKey("HelloWorldKey",map);
System.out.println("流程实例的Id: "+pi.getId());//220001
System.out.println("流程定义的Key: "+pi.getProcessDefinitionKey());//demo
System.out.println("流程定义的Id: "+pi.getProcessDefinitionId());//demo:4:70004
System.out.println("流程定义的Name: "+pi.getProcessDefinitionName());//null
System.out.println("流程定义的Version: "+pi.getProcessDefinitionVersion());//null
}
@Test
public void findMyPersonTask() {
System.out.println("--------得到申请--------");
String assignee = "刘二狗i";//代办人姓名。这里对应上面${pm},得到的是刘二狗的所有代办
List taskList = processEngine.getTaskService()//获取任务service
.createTaskQuery()//创建查询对象
.taskAssignee(assignee)//指定查询人
.list();
if (taskList.size() > 0) {
for (Task task : taskList) {
System.out.println("代办任务ID:" + task.getId());//180007
System.out.println("代办任务name:" + task.getName());//申请
System.out.println("代办任务创建时间:" + task.getCreateTime());//Wed Aug 28 14:07:09 CST 2019
System.out.println("代办任务办理人:" + task.getAssignee());//刘二狗i
System.out.println("流程实例ID:" + task.getProcessInstanceId());//220001
System.out.println("执行对象ID:" + task.getExecutionId());//97501
System.out.println("代办任务的key"+task.getTaskDefinitionKey());
}
}
}
@Test
public void completeTask(){
System.out.println("--------申请审批并提交----------");
Map map = new HashMap();
map.put("dm", "哈哈哈");//这里将下一个task的代办人提交
String taskId = "187507";//这个id是上个方法得到的taskId
//如果遇到这样的场景,你需要将你的申请信息传递给代办人,可以用下面这种传值的方式,取值getVariable()
//注意下面的三个参数,第一个是taskID,第二个是传递的key,第三个是传递的value,如果value是对象的话必须要实现序列化
processEngine.getTaskService().setVariable(taskId, "备注", "嗯,很好。这是我的备注");
processEngine.getTaskService().complete(taskId,map);//完成任务
System.out.println("申请审批完成,任务ID"+taskId);//97506
}
@Test
public void findMyPersonTask2() {
System.out.println("----------得到经理代办----------");
String assignee = "哈哈哈";
List taskList = processEngine.getTaskService()//获取任务service
.createTaskQuery()//创建查询对象
.taskAssignee(assignee)//指定查询人
.list();
TaskService taskService = processEngine.getTaskService();
if (taskList.size() > 0) {
for (Task task : taskList) {
System.out.println("代办任务ID:" + task.getId());//100004
System.out.println("代办任务name:" + task.getName());//经理审批
System.out.println("代办任务创建时间:" + task.getCreateTime());//Wed Aug 28 13:05:23 CST 2019
System.out.println("代办任务办理人:" + task.getAssignee());//哈哈哈
System.out.println("流程实例ID:" + task.getProcessInstanceId());//97501
System.out.println("执行对象ID:" + task.getExecutionId());//97501
String beiZhu =(String) taskService.getVariable(task.getId(), "备注");//“name”对应前面set的variableName
System.out.println("备注是:"+beiZhu);
}
}
}
@Test
public void completeTask1(){
System.out.println("---------经理审批-----------");
Map map = new HashMap();
map.put("gm", "总经理");
String taskid = "190004";//这个id用的是提交给经理的taskId
TaskService taskService = processEngine.getTaskService();
String beiZhu =(String) taskService.getVariable(taskid, "备注");//“name”对应前面set的variableName
System.out.println("备注是:"+beiZhu);
processEngine.getTaskService().complete(taskid,map);//完成任务
System.out.println("经理审批完成,任务ID"+taskid);//85003
}
@Test
public void findMyPersonTask3() {
System.out.println("----------得到总经理代办----------");
String assignee = "总经理";
List taskList = processEngine.getTaskService()//获取任务service
.createTaskQuery()//创建查询对象
.taskAssignee(assignee)//指定查询人
.list();
if (taskList.size() > 0) {
for (Task task : taskList) {
System.out.println("代办任务ID:" + task.getId());//77504
System.out.println("代办任务name:" + task.getName());//总经理审批
System.out.println("代办任务创建时间:" + task.getCreateTime());//Wed Aug 28 14:17:01 CST 2019
System.out.println("代办任务办理人:" + task.getAssignee());//总经理
System.out.println("流程实例ID:" + task.getProcessInstanceId());//72501
System.out.println("执行对象ID:" + task.getExecutionId());//72501
}
}
}
@Test
public void completeTask2(){
System.out.println("---------总经理审批-----------");
String taskid = "77504";//这个id用的是提交给经理的taskId
TaskService taskService = processEngine.getTaskService();
processEngine.getTaskService().complete(taskid);//完成任务
System.out.println("经理审批完成,任务ID"+taskid);//77504
}
/**
* 根据流程实例id删除流程实例
*/
@Test
public void test12(){
String processInstanceID = "220001";//这个实例id是创建流程实例的时候得到的,也可以通过taskID得到。
processEngine.getRuntimeService().deleteProcessInstance(processInstanceID, "我愿意,结束。咋地啦!!!");
}
}
流程图,这里没法发文件。我给个截图。完整demo下载。没积分评论找我要。
上一篇:Activiti入门
下一篇 :Activiti网关