引言
最近在学习流程引擎,以下是对流程引擎的知识总结,
学习来源教程地址:https://www.bilibili.com/video/BV1Ut411y7NT
参考博客:https://blog.youkuaiyun.com/qq_31776219/category_9268778.html
其他视频教程地址:https://www.bilibili.com/video/BV1H54y167gf?p=104
1.数据库
ACT_RE_*:’RE’代表 repository。带此前缀的表包含的是静态信息,如,流程定义、流程的资源(图片、规则,等)。
ACT_RU_*:’RU’代表 runtime。就是这个运行时的表存储着流程变量、用户任务、变量、作业,等中的运行时的数据。
ACT_ID_*:’ID’代表 identity。这些表包含着标识的信息,如用户、用户组、等等。
ACT_HI_*:’HI’代表history。就是这些表包含着历史的相关数据,如结束的流程实例、变量、任务、等等。
ACT_GE_*:普通数据,各种情况都使用的数据。
常用数据库
2.核心API
//必须创建activiti.cfg.xml 并配置好数据库的信息
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//流程图的部署 修改 删除的服务器 act_ge_bytearray, act_re_deployment, act_re_model, act_re_procdef
RepositoryService repositoryService = processEngine.getRepositoryService();
//流程的运行 act_ru_event_subscr, act_ru_execution, act_ru_identitylink, act_ru_job, act_ru_task, act_ru_variable
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
//查询历史记录的服务器act_hi_actinst, act_hi_attachment, act_hi_comment, act_hi_detail, act_hi_identitylink, act_hi_procinst, act_hi_taskinst, act_hi_varinst
HistoryService historyService = processEngine.getHistoryService();
//页面表单的服务器[了解]
FormService formService = processEngine.getFormService();
//对工作流的用户管理的表的操作act_id_group, act_id_info, act_id_membership, act_id_user
IdentityService identityService = processEngine.getIdentityService();
//管理器
ManagementService managementService = processEngine.getManagementService();
常用API
3.actiBPM
Idea下画流程图的工具,下载参考
4.流程变量
流程变量在整个工作流中扮演很重要的作用。例如:请假流程中有请假天数、请假原因等一些参数都为流程变量的范围。流程变量的作用域范围是只对应一个流程实例。也就是说各个流程实例的流程变量是不相互影响的。流程实例结束完成以后流程变量还保存在数据库中(存放到流程变量的历史表中)。
设置流程变量
TaskService taskService = this.processEngine.getTaskService();
String taskId = "5002";
taskService.setVariable(taskId,"请假原因","生病了");
获取流程变量
TaskService taskService = this.processEngine.getTaskService();
String taskId = "5002";
taskService.getVariable(taskId,"请假原因");
5.网关
排他网关
1)一个排他网关对应一个以上的顺序流
2)由排他网关流出的顺序流都有个conditionExpression元素,在内部维护返回boolean类型的决策结果。
3)决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索如果发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出。
4)如果没有任何一个出口符合条件,则抛出异常
5)使用流程变量,设置连线的条件,并按照连线的条件执行工作流,如果没有条件符合的条件,则以默认的连线离开。
并行网关
1)一个流程中流程实例只有1个,执行对象有多个
2)并行网关的功能是基于进入和外出的顺序流的:
分支(fork): 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
汇聚(join): 所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。
3)并行网关的进入和外出都是使用相同节点标识
4)如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。
5)并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。
并行网关不需要是“平衡的”(比如, 对应并行网关的进入和外出节点数目不一定相等)。
5.Demo例子
activiti.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- <context:property-placeholder location="db.properties" system-properties-mode="FALLBACK"/> -->
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/activiti"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!-- <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/0705activiti"></property>
<property name="jdbcUsername" value="root"></property>
<property name="jdbcPassword" value="123456"></property> -->
<property name="dataSource" ref="dataSource"></property>
<!--
flase: 默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常。
true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建。
create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)。
drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)。 -->
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
</beans>
TestActiviti
package com.sxt.a_init;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 流程引擎
*
* @author zhoufan
*/
public class TestActiviti {
//得到流程引擎
private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**
* 部署流程
*/
@Test
public void intiTables2() {
//得到流程部署的service
RepositoryService repositoryService = this.processEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment()
.name("hello")
.addClasspathResource("hello.bpmn")
.addClasspathResource("hello.png")
.deploy();
System.out.println("部署成功:流程部署ID:" + deploy.getId());
}
/**
* 启动流程
*/
@Test
public void startProcess() {
RuntimeService runtimeService = this.processEngine.getRuntimeService();
String processDefinitionId = "myProcess_1:2:5004";
runtimeService.startProcessInstanceById(processDefinitionId);
System.out.println("流程启动成功");
}
/**
* 查询任务
*/
@Test
public void findTask() {
TaskService taskService = this.processEngine.getTaskService();
// 办理人
String assignee = "zhangsan";
List<Task> list = taskService.createTaskQuery().taskAssignee(assignee).list();
if (null != list && list.size() > 0) {
for (Task task : list) {
System.out.println("任务ID:" + task.getId());
System.out.println("流程实例ID:" + task.getProcessInstanceId());
System.out.println("执行实例ID:" + task.getExecutionId());
System.out.println("流程定义ID:" + task.getProcessDefinitionId());
System.out.println("任务名称:" + task.getName());
System.out.println("任务办理人:" + task.getAssignee());
System.out.println("################################");
}
}
}
/**
* 办理任务
*/
@Test
public void completeTask() {
TaskService taskService = this.processEngine.getTaskService();
// 任务ID
String taskId = "5002";
taskService.complete(taskId);
System.out.println("办理任务");
}
/**
* 表单提交流程变量
*/
@Test
public void submit() {
//页面表单的服务器
FormService formService = this.processEngine.getFormService();
// 流程ID
String processDefinitionId = "myProcess_1:1:4";
Map map = new HashMap<String, Object>();
map.put("name", "zhansan");
map.put("day", "1");
map.put("reason", "I think ill");
formService.submitStartFormData(processDefinitionId, map);
System.out.println("提交表单");
}
}