Activiti7是开源的工作流引擎
工作流(Workflow)就是工作流程的计算模型,即将工作流程中的工作如何前后组织在一起的逻辑和规则在计算机中以恰当的模型进行表示并对其实施计算。工作流要解决的主要问题是:为实现某个业务目标,在多个参与者之间,利用计算机,按某种预定规则自动传递文档、信息或者任务。
插件名字
actiBPM
离线安装
IDEA新版本需要到插件市场下载并离线安装。
重启IDEA
所有符号
完整的工作流由StartEvent
开始,由EndEvent
结束,中间穿插着各种Task
任务,Gateway
负责构建复杂的流程(如请假审批,请假1天的,和请假3天的流程是不一样的),SubProcess
子流程,Annotation
注解。
创建数据库
创建项目
导入依赖
<properties>
<activiti.version>7.0.0.Beta3activiti.version>
properties>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-engineartifactId>
<version>${activiti.version}version>
<exclusions>
<exclusion>
<artifactId>mybatisartifactId>
<groupId>org.mybatisgroupId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-springartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-bpmn-modelartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-bpmn-converterartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-json-converterartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-bpmn-layoutartifactId>
<version>${activiti.version}version>
dependency>
创建配置文件
activiti.cfg.xml
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl"
value="jdbc:mysql://**********/activiti-service-dev?useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="**********"/>
bean>
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"/>
<property name="databaseSchemaUpdate" value="true"/>
bean>
beans>
生成表结构
package com.qiang.activiti;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@Slf4j
class ActivitiServiceApplicationTests {
/**
* 生成表结构
*/
@Test
public void testCreateTable() {
ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
log.info("testCreateTable{}", defaultProcessEngine);
}
}
启动程序
运行结果
生成25张表。
新建文件
新建一个请假流程
整体流程配置,设置流程ID为leave
,名字为员工请假审批流程
。
配置提交请假申请的责任人为worker
。
配置部门经理审批的责任人为manager
。
配置财务主管审批的责任人为financer
。
将BPMN文件复制一份为XML文件
选择BPMN设计器
查看流程图
导出流程图
/**
* 部署流程(单个流程)
*/
@Test
public void testDeployment() {
// 创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取 repositoryService 实例
RepositoryService repositoryService = processEngine.getRepositoryService();
// 使用 repositoryService 进行部署
Deployment deployment = repositoryService.createDeployment()
// 对应的 bpmn 文件
.addClasspathResource("bpmn/leave.bpmn")
// 对应的流程图文件,命名规范(流程ID.png)为 leave.png/jpg/gif/svg
.addClasspathResource("bpmn/image/leave.png")
.name("请假申请流程")
.deploy();
// 获取部署后的信息
log.info("部署的流程ID:{}", deployment.getId());
log.info("部署流程名称:{}", deployment.getName());
}
启动实例
数据已经存到数据库
包括XML文件以及图片文件
将bpmn文件以及流程图文件按规定名字打成压缩包
文件位置
实例代码
/**
* 批量部署流程
*/
@Test
public void testDeploymentByZip() {
InputStream inputStream = this
.getClass()
.getClassLoader().getResourceAsStream("bpmn/zip/test.zip");
assert inputStream != null;
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
// 创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取 repositoryService 实例
RepositoryService repositoryService = processEngine.getRepositoryService();
// 使用 repositoryService 进行部署
Deployment deployment = repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
// 获取部署后的信息
log.info("部署的流程ID:{}", deployment.getId());
log.info("部署流程名称:{}", deployment.getName());
}
启动实例
数据已经存到数据库
包括XML文件以及图片文件
根据流程 ID 启动流程
/**
* 启动流程实例
*/
@Test
public void testStartProcess() {
// 创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取 runtimeService 实例
RuntimeService runtimeService = processEngine.getRuntimeService();
// 根据流程 ID 启动流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave");
// 获取启动流程后的信息
log.info("流程定义ID:{}", processInstance.getProcessDefinitionId());
log.info("流程实例ID:{}", processInstance.getId());
log.info("当前活动ID:{}", processInstance.getActivityId());
}
执行结果
启动流程实例后,该节点到达了提交请假申请的节点,需要任务负责人查询当前负责的待办任务(当前负责人为worker要提交请假申请)。
/**
* 查询当前负责人的待办任务
*/
@Test
public void testFindPersonalTaskList() {
// 当前负责人
String assignee = "worker";
// 创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 创建 taskService
TaskService taskService = processEngine.getTaskService();
// 根据流程 Key 和任务负责人查询代办任务
List<Task> tasks = taskService.createTaskQuery()
// 流程 Key
.processDefinitionKey("leave")
// 负责人
.taskAssignee(assignee)
.list();
tasks.forEach(task -> {
log.info("流程实例ID:{}", task.getProcessInstanceId());
log.info("流程任务ID:{}", task.getId());
log.info("流程任务负责人:{}", task.getAssignee());
log.info("流程任务名称:{}", task.getName());
});
}
启动实例
当前任务节点到了worker审批,根据查询到的任务ID完成任务。
/**
* 完成任务
*/
@Test
public void testCompleteTask() {
// 当前负责人
String assignee = "worker";
// 创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 创建 taskService
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processDefinitionKey("leave")
// 负责人
.taskAssignee(assignee)
// 返回一个任务
.singleResult();
// 根据任务ID完成任务
taskService.complete(task.getId());
}
启动实例
完成任务后,再次查询worker的代办任务已经没有了,任务已经流转到了部门经理审批了,此时可以查询到manager的待办任务了。
/**
* 查询当前负责人的待办任务
*/
@Test
public void testFindPersonalTaskList() {
// 当前负责人
String assignee = "manager";
// 创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 创建 taskService
TaskService taskService = processEngine.getTaskService();
// 根据流程 Key 和任务负责人查询代办任务
List<Task> tasks = taskService.createTaskQuery()
// 流程 Key
.processDefinitionKey("leave")
// 负责人
.taskAssignee(assignee)
.list();
tasks.forEach(task -> {
log.info("流程实例ID:{}", task.getProcessInstanceId());
log.info("流程任务ID:{}", task.getId());
log.info("流程任务负责人:{}", task.getAssignee());
log.info("流程任务名称:{}", task.getName());
});
}
启动实例
查询当前流程定义下有哪些实例正在跑。
/**
* 查询当前流程定义
*/
@Test
public void testQueryProcessInstance(){
// 流程定义Key
String processDefinitionKey = "leave";
// 创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取 runtimeService 实例
RuntimeService runtimeService = processEngine.getRuntimeService();
List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery()
.processDefinitionKey(processDefinitionKey)
.list();
processInstances.forEach(processInstance -> {
log.info("===========================================");
log.info("流程实例ID:{}", processInstance.getProcessInstanceId());
log.info("所属流程定义ID:{}", processInstance.getProcessDefinitionId());
log.info("是否执行完成:{}", processInstance.isEnded());
log.info("是否暂停流程:{}", processInstance.isSuspended());
log.info("当前活动标识:{}", processInstance.getActivityId());
log.info("业务关键字:{}", processInstance.getBusinessKey());
});
}
启动实例
这里两个流程
查询在一个BPMN文件中定义了哪些流程。
/**
* 查询所有流程定义
*/
@Test
public void testQueryProcessDefinition() {
// 创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取 repositoryService 实例
RepositoryService repositoryService = processEngine.getRepositoryService();
// 获取 processDefinitionQuery 实例
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
List<ProcessDefinition> processDefinitions = processDefinitionQuery.processDefinitionKey("leave")
// 按照版本排序
.orderByProcessDefinitionVersion()
// 倒序
.desc()
// 返回集合
.list();
processDefinitions.forEach(processDefinition -> {
log.info("===========================================");
log.info("流程定义ID:{}", processDefinition.getId());
log.info("流程定义NAME:{}", processDefinition.getName());
log.info("流程定义KEY:{}", processDefinition.getKey());
log.info("流程定义Version:{}", processDefinition.getVersion());
log.info("流程部署ID:{}", processDefinition.getDeploymentId());
});
}
启动实例
/**
* 删掉流程
*/
@Test
public void testDeleteDeployment() {
// 流程部署Id
String deploymentId = "1";
// 创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取 repositoryService 实例
RepositoryService repositoryService = processEngine.getRepositoryService();
// 根据Id删除,如果该流程有实例正在启动则报错
repositoryService.deleteDeployment(deploymentId);
// 根据Id删除,如果该流程有实例正在启动则会级联删除
repositoryService.deleteDeployment(deploymentId,true);
}
设置IDEA的编码格式为UTF-8。
加上这一行然后重启IDEA即可。
-Dfile.encoding=UTF-8
乱码解决。
问题:
org.activiti.engine.ActivitiException: Could not update Activiti database schema: unknown version from database: '6.0.0.4'
解决:
<activiti.version>6.0.0activiti.version>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-springartifactId>
<version>${activiti.version}version>
dependency>
作者(Author):小强崽
来源(Source):https://www.wuduoqiang.com/archives/Activiti7工作流
协议(License):署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
版权(Copyright):商业转载请联系作者获得授权,非商业转载请注明出处。 For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source.