概述
工作中需要用到工作流引擎,研究一下activiti
开发
- resource下准备activiti.cfg.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 固定模式下bean的id固定-->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<!-- 配置数据库相关信息-->
<!-- 数据库驱动-->
<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<!-- 数据库链接-->
<property name="jdbcUrl" value="" />
<!-- 数据库用户名密码-->
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="" />
<!-- 如果数据库中存在表,那么直接使用,不存在就创建-->
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
- 创建
ProcessEngine就会自动创建对应的表
public void createDB(){
// 需要使用activiti听过的工具类。 默认会从resources下肚去activiti.cfg.xml的文件
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
}
表介绍
| 表分类 | 表名 | 解释 |
|---|---|---|
| 一般数据 | ||
| ACT_GE_BYTEARRAY | 通用的流程定义和流程资源 | |
| ACT_GE_PROPERTY | 系统相关属性 | |
| 流程历史记录 | ||
| ACT_HI_ACTINST | 历史的流程实例 | |
| ACT_HI_ATTACHMENT | 历史流程附件 | |
| ACT_HI_COMMENT | 历史流程说明信息 | |
| ACT_HI_DETAIL | 历史的流程运行中的细节信息 | |
| ACT_HI_IDENTITYLINK | 历史的流程运行过程中用户关系 | |
| ACT_HI_PROCINTST | 历史的流程实例 | |
| ACT_HI_TASKINST | 历史的任务实例 | |
| ACT_HI_VARINST | 历史的流程运行中的变量信息 | |
| 流程定义表 | ||
| ACT_RE_DEPLOYMENT | 部署单元信息 | |
| ACT_RE_MODEL | 模型信息 | |
| ACT_RE_PROCDEF | 已部署的流程定义 | |
| 运行实例表 | ||
| ACT_RU_EVENT_SUBSCR | 运行时事件 | |
| ACT_RU_EXECUTION | 运行时流程执行实例 | |
| ACT_RU_IDENTITYLINK | 运行时用户关系信息,存储任务节点与参与者的相关信息 | |
| ACT_RU_JOB | 运行时作业 | |
| ACT_RU_TASK | 运行时任务 | |
| ACT_RU_VARIABLE | 运行时变量表 |
体系架构图
Activiti入门
我们来创建并启动一个工作流
- 定义流程,按照BPMN的规范,使用流程定义工具,用流程符号把整个流程描述出来
- 部署流程,把画好的流程定义文件加载到数据库中,生成表的数据
- 启动流程,使用java代码操作数据库表中的内容
流程符号
- 事件Event
- 活动Activity
- 网关, 网关用来处理决策
流程设计器使用
利用idea的工具绘图
流程部署
流程部署就是把画好饿BPMN图放到数据库中
public void createDeployment(){
// 1. processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService service = processEngine.getRepositoryService();
Deployment deploy = service.createDeployment()
.name("出差申请流程")
.addClasspathResource("bpmn/evection.bpmn20.xml")
.addClasspathResource("bpmn/evection.png")
.deploy();
System.out.println("id= "+deploy.getId());
System.out.println("name= "+deploy.getName());
}
流程定义部署
- 使用流程设计器,使用流程符号,画出流程图,bpmn文件,png文件都是流程资源文件,用来描述流程,流程中需要的节点,节点负责人.
- 把流程的资源文件进行部署上传到数据库中,使用java代码进行流程部署,一次部署操作:
ACT_RE_DEPLOYMENT会生产一条记录.ACT_RE_PROCDEF会生成流程定义信息 - deployment和procdef表一对多的关系.在procdef表中可用有多条记录,每条记录对应一个流程的定义信息
流程启动
public void startProcess(){
// 1. 创建processEngine
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取runtimeService
RuntimeService service = engine.getRuntimeService();
// 3. 根据流程id启动流程. 找的是act_re_procdef 的id
ProcessInstance instance = service.startProcessInstanceByKey("myEvection");
System.out.println(instance.getProcessDefinitionId());
System.out.println(instance.getId());
System.out.println(instance.getActivityId());
}
在启动了一个工作流之后,我们再来看一下相应的表有没有什么变化
- ACT_GE_PROPERTY
记录总体信息 - ACT_HI_ACTINST
流程实例执行历史 - ACT_HI_IDENTITYLINK
流程的参与用户信息历史 - ACT_HI_PROCINST
流程实例历史信息 - ACT_HI_TASKINST
流程任务历史信息 - ACT_RU_EXECUTION
流程正在执行信息 - ACT_RU_IDENTITYLINK
流程的参与用户信息 - ACT_RU_TASK
任务信息
个人查看任务历史记录
public void findPersonalTaskList(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
TaskService service = engine.getTaskService();
List<Task> list = service.createTaskQuery()
.processDefinitionKey("myEvection")
.taskAssignee("zhangsan")
.list();
for (Task task : list) {
// 流程实例id
System.out.println(task.getProcessInstanceId());
// 任务id
System.out.println(task.getId());
// 任务负责人
System.out.println(task.getAssignee());
// 任务名称
System.out.println(task.getName());
}
}
执行这个程序中,真实执行的sql语句如下
SELECT DISTINCT
RES.*
FROM
ACT_RU_TASK RES
INNER JOIN ACT_RE_PROCDEF D ON RES.PROC_DEF_ID_ = D.ID_
WHERE
RES.ASSIGNEE_ = zhangsan
AND D.KEY_ = myEvection
ORDER BY
RES.ID_ ASC
LIMIT 2147483647 OFFSET 0
其实就是运行时任务表内连已部署的流程定义表 然后查询运行时任务的ASSIGNEE 和 key
完成个人任务
我们刚才启动了流程,并且查看了任务记录,现在流程还停留在个人流程.我们需要让流程往下走
public void completTask(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
TaskService service = engine.getTaskService();
service.complete("5005");
}
执行完上面方法之后我们再来看数据库表中有什么变化
- ACT_RU_TASK
可以看到在运行时任务表中已经指向了经理审批
- ACT_HI_TASKINST
历史任务表中创建出差申请任务结束时间已经有了,并且多了一个经理审批任务
- ACT_HI_IDENTITYLINK
用户关系表中插入了一条经理审批的执行人
查询流程定义
流程定义查询出来的是ACT_RE_PROCDEF这张表
public void queryProcessDefinition(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("myEvection")
.orderByProcessDefinitionVersion()
.desc()
.list();
for (ProcessDefinition definition : list) {
System.out.println("流程定义id"+definition.getId());
System.out.println("流程定义name"+definition.getName());
System.out.println("流程定义key"+definition.getKey());
System.out.println("流程定义version"+definition.getVersion());
}
}
流程删除
public void deleteDeployment(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
repositoryService.deleteDeployment("1");
}
在删除流程的时候如果还有没走完的流程删除会出现异常,如果强制删除的话,用
repositoryService.deleteDeployment("1",true);