ProcessEngine:
ProcessEngines.getDefaultProcessEngine()会在第一次调用时 初始化并创建一个流程引擎,以后再调用就会返回相同的流程引擎。 使用对应的方法可以创建和关闭所有流程引擎:ProcessEngines.init()和ProcessEngines.destroy()。
RepositoryService:
可能是使用Activiti引擎时最先接触的服务。 它提供了管理和控制发布包和流程定义的操作。它包含了一个流程每个环节的结构和行为。可以自由选择把任意资源包含到发布包中。 既可以把一个单独的BPMN 2.0 xml文件放到发布包里,也可以把整个流程和相关资源都放在一起。发布一个发布包,意味着把它上传到引擎中,所有流程都会在保存进数据库之前分析解析好。
TaskService:
任务是由系统中真实人员执行的,所有与任务有关的功能都包含在TaskService中:
查询分配给用户或组的任务。
创建独立运行任务。这些任务与流程实例无关。
手工设置任务的执行者,或者这些用户通过何种方式与任务关联。
认领并完成一个任务。认领意味着一个人期望成为任务的执行者, 即这个用户会完成任务。完成意味着“做这个任务要求的事情”。 通常来说会有很多种处理形式。
IdentityService:
它可以管理(创建,更新,删除,查询...)群组和用户。
HistoryService:
提供了Activiti引擎手机的所有历史数据。 在执行流程时,引擎会保存很多数据(根据配置),比如流程实例启动时间,任务的参与者, 完成任务的时间,每个流程实例的执行路径,等等。 这个服务主要通过查询功能来获得这些数据。
RuntimeService:
执行管理,包括启动,推进,删除流程实例等操作,在流程运行时对流程实例进行管理与控制。
ACT_GE_*: “GE”代表“General”(通用),用在各种情况下。
ACT_HI_*: “HI”代表“History”(历史),这些表中保存的都是历史数据,比如执行过的流程实例、变量、任务,等等。
指定保存历史记录级别:
Ønone: 不保存任何历史记录,可以提高系统性能;
Øactivity:保存所有的流程实例、任务、活动信息;
Øaudit:也是Activiti的默认级别,保存所有的流程实例、任务、活动、表单属性;
Øfull:最完整的历史记录,除了包含audit级别的信息之外还能保存详细,例如:流程变量。
ACT_ID_*: “ID”代表“Identity”(身份),这些表中保存的都是身份信息,如用户和组以及两者之间的关系。如果Activiti被集成在某一系统当中的话,这些表可以不用,可以直接使用现有系统中的用户或组信息;
ACT_RE_*: “RE”代表“Repository”(仓库),这些表中保存一些‘静态’信息,如流程定义和流程资源(如图片、规则等);
ACT_RU_*: “RU”代表“Runtime”(运行时),这些表中保存一些流程实例、用户任务、变量等的运行时数据。Activiti只保存流程实例在执行过程中的运行时数据,并且当流程结束后会立即移除这些数据,这是为了保证运行时表尽量的小并运行的足够快;
ActivitiWrongDbException:当Activiti引擎发现数据库版本号和引擎版本号不一致时抛出。
ActivitiOptimisticLockingException:对同一数据进行并发方法并出现乐观锁时抛出。
ActivitiClassLoadingException:当无法找到需要加载的类或在加载类时出现了错误(比如,JavaDelegate,TaskListener等。
ActivitiObjectNotFoundException:当请求或操作的对应不存在时抛出。
ActivitiIllegalArgumentException:这个异常表示调用Activiti API时传入了一个非法的参数,可能是引擎配置中的非法值,或提供了一个非法制,或流程定义中使用的非法值。
ActivitiTaskAlreadyClaimedException:当任务已经被认领了,再调用taskService.claim(...)就会抛出。
Demo代码演示:
// 创建流程引擎对象
private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 流程定义
processEngine.getRepositoryService()
.createDeployment()
.name("test")
.addClasspathResource("activitiTest.bpmn")
.deploy();
// 流程启动
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceByKey("activitiTest");
System.out.println("pId: " + pi.getId() + ", pName: " + pi.getName());
// 查询指定代理人的任务,进行执行
TaskService taskService = processEngine.getTaskService();
// 根据assignee查询员工任务
List tasks = taskService.createTaskQuery().taskAssignee("员工").list();
for (Task task : tasks) {
System.out.println("taskId: " + task.getId() + ", taskAssignee: " + task.getAssignee());
// 添加员工基本信息
taskService.setVariable(task.getId(), "请假人", "原野" + task.getId());
taskService.setVariable(task.getId(), "请假时长", 7);
taskService.setVariable(task.getId(), "日期", new Date());
// 提交申请(执行任务)
taskService.complete(task.getId());
}
/*提交申请后,任务流向下一个节点*/
Task task1 = taskService.createTaskQuery().taskAssignee("上司").singleResult();
System.out.println("taskId: " + task1.getId() + ", taskAssignee: " + task1.getAssignee() + ", taskName: " + task1.getName() + ", taskTime: " + task1.getCreateTime());
// 上司查看员工基本信息
String name = (String) taskService.getVariable(task1.getId(), "请假人");
Integer time = (Integer) taskService.getVariable(task1.getId(), "请假时长");
Date date = (Date) taskService.getVariable(task1.getId(), "日期");
System.out.println("name: " + name + ", time: " + time + ", date: " + date);
// 上司审批完成
taskService.complete(task1.getId());
// 流程走到结束事件,流程结束!
以上是一个简单的流程Demo,演示一个员工申请请假,上司审批的过程。
首先需要定义bpmn流程图,然后针对该流程图(xml)的操作是:
定义流程 -> 启动流程 ->执行流程步骤 -> 结束
在这个过程中,先通过RepositoryService对象对流程进行定义,流程的xml信息等会被加载到数据库表中,并创建流程解析和部署的数据。然后启动流程通过RuntimeService对象指定xml的
简述:
首先创建一个ProcessEngine的流程引擎对象,该对象创建过程中会检查数据库中是否存在了activiti需要的基础表,不存在则创建。
根据RepositoryService创建部署对象,通过addClasspathResource().deploy对指定的bpmn文件进行加载,在数据库中保存这些基本信息后,流程发布完成,数据库中存储了xml和流程发布的基本信息后,可以进行流程启动。
细节:
在创建流程引擎的过程中,会首先判断数据库中是否存在了基本的表结构,如果没有就会初始化表结构(创建28张表/activiti6.0之前版本是23张)
之后往ACT_GE_PROPERTY(系统相关属性表)插入四条数据,保存工作流引擎的基本信息。如果原本的表结构以及系统相关属性纪录已经存在,则不做上述操作。
创建流程引擎后的ACT_GE_PROPERTY,字段分别是属性名,属性值,版本号
在定义流程的过程中,ACT_GE_PROPERTY表中的next.dbid的value,作为ACT_RE_DEPLOYMENT(流程部署信息表)的主键id,生成一条流程部署纪录。
同时往ACT_GE_BYTEARRAY(流程资源表)和ACT_RE_PROCDEF(流程解析表)插入一条纪录,这两条纪录都关联部署信息表的id。
然后对ACT_GE_PROPERTY表纪录修改,修改后的next.dbid作为下一个流程部署信息纪录的主键。
如果对同一个流程部署两次的话,ACT_GE_BYTEARRAY(流程资源表),ACT_RE_PROCDEF(流程解析表),ACT_GE_PROPERTY(流程部署表)都会相应的增加一条纪录。在ACT_RE_PROCDEF表中有VERSION字段,在根据key启动流程的时候是基于VERSION最大的记录启动。
删除一个流程定义:
因为指定了级联, ACT_RE_DEPLOYMENT表id为10001这条纪录被删除,ACT_GE_BYTEARRAY,ACT_RE_PROCDEF关联这条纪录的数据也被删除。
简述:
因为在上一步已经发布了流程,那么在这里就是针对发布的流程进行一个启动,发布的流程xml信息保存在了数据库中,这里通过RuntimeService对象的startProcessInstanceByKey()来启动流程(也可以通过其他方法),参数为xml的
细节:
启动流程一般是根据startProcessInstanceByKey()来启动流程,也就是ACT_RE_PROCDEF(流程解析表)的Key_字段,XML文件中
整个启动对数据库表的操作过程为:
1. 根据startProcessInstanceByKey()拿Key_查询流程解析表,获得流程解析表中的一条数据,如果存在重复Key_数据,取Max(版本号)的一条。
2. 因为ACT_RE_PROCDEF(流程解析表)关联了ACT_RE_DEPLOYMENT(部署信息表),而ACT_GE_BYTEARRAY(流程资源表)又关联了ACT_RE_DEPLOYMENT,所以在流程启动时就拿到了发布流程的所有信息。
3. 开始启动流程,往ACT_HI_PROCINST(历史流程实例)创建历史实例记录,ACT_HI_ACTINST(历史节点)创建历史节点记录。ACT_HI_TASKINST(历史任务表),ACT_HI_IDENTITYLINK(历史流程人员表)添加纪录(如果存在)
历史实例:
历史节点:
历史任务:
历史流程人员:
4. 在ACT_RU_EXECUTION(运行时流程实例表)创建流程实例记录,如果该节点存在任务则在ACT_RU_TASK(运行时任务表)创建任务记录,ACT_RU_IDENTITYLINK(运行流程人员表)创建流程中任务办理人员记录。如果进行了setVariables()则在ACT_HI_VARINST(历史变量表),ACT_RU_VARIABLE(运行变量表)添加变量信息
5.
运行实例:
运行任务:
运行流程人员:
历史变量以及运行时变量:
其中所有历史纪录表关联了实例表,而实例表关联流程解析表id
运行时表围绕实例表和解析表关联,运行实例表关联解析表id
简述:
在流程启动后,流程走向了用户任务节点,那么该节点就会有一条在ACT_RU_TASK(运行任务)中的代办任务记录,通过创建查询对象,根据assignee查询表中ASSIGNEE_为员工的记录,查到这些任务后,通过setVarable往ACT_RU_VARIABLE,ACT_HI_VARINST添加变量信息,然后通过complete()完成指定的任务,流程流向下一个节点。下一个节点同上一样,查询自己的任务,是否完成(批准),查看参数变量。
细节:
首先会根据api去ACT_RU_TASK(运行任务表)查询指定的任务,这里是根据taskAssignee(),也就是指定人查询,查询的条件为运行任务表中的ASSIGNEE_字段,查到的任务返回后,得到taskId。
setVariable(),意味着往ACT_HI_VARINST,ACT_RU_VARIABLE变量表中添加变量信息,该表关联流程实例表,运行时变量表在执行完后会删除,历史纪录会保存下来。
执行complete(taskId)方法时,指定的运行时任务完成,那么ACT_RU_TASK表中删除该条任务记录,历史纪录表中update结束时间,流程流向下一个节点,如果下一个节点是任务节点,那么又会创建新的任务,以及历史任务。