(外链:以下是一整套Activiti7 的内容,有兴趣的可以看看)
- (一)Activiti7 之工作流介绍:https://blog.csdn.net/qq_23845083/article/details/131292415
- (二)Activiti7 之BPMN:https://blog.csdn.net/qq_23845083/article/details/131292515
- (三)Activiti7 之新手入门:https://blog.csdn.net/qq_23845083/article/details/131292627
- (四)Activiti7 之实战应用:https://blog.csdn.net/qq_23845083/article/details/131292700
1 关于 Activiti 的一些思考(本文的重点)
- activiti7 如何入门?
- 业务参数如何传参和设值?
- 排他网关和并行网关怎么使用?
- 任务监听器如何使用?
2 了解Activiti
2.1 activiti.cfg.xml
activiti的引擎配置文件,包括:ProcessEngineConfiguration的定义、数据源定义、事务管理器等。此文件其实就是一个spring配置文件。
2.2 ProcessEngineConfiguration
通过 ProcessEngineConfiguration 可以创建工作流引擎 ProceccEngine,该类主要负责读取 activiti.cfg.xml 的配置。
public static ProcessEngineConfiguration createProcessEngineConfigurationFromResourceDefault() {
return createProcessEngineConfigurationFromResource("activiti.cfg.xml", "processEngineConfiguration");
}
2.3 ProcessEngine
相当于一个门面接口,通过ProcessEngineConfiguration创建processEngine,通过ProcessEngine创建各个service接口,具体代码逻辑由 ProcessEngineImpl.class 实现。
public interface ProcessEngine {
String VERSION = "7.0.0.0";
String getName();
void close();
RepositoryService getRepositoryService();
RuntimeService getRuntimeService();
TaskService getTaskService();
HistoryService getHistoryService();
ManagementService getManagementService();
DynamicBpmnService getDynamicBpmnService();
ProcessEngineConfiguration getProcessEngineConfiguration();
}
2.4 Service 核心管理类
- RepositoryService:是activiti的资源管理类,提供了管理和控制流程发布包和流程定义的操作。
- RuntimeService:Activiti的流程运行管理类。可以从这个服务类中获取很多关于流程执行相关的信息。
- TaskService:Activiti的任务管理类。可以从这个类中获取任务的信息。
- HistoryService:Activiti的历史管理类,可以查询历史信息,执行流程时,引擎会保存很多数据(根据配置),比如流程实例启动时间,任务的参与者, 完成任务的时间,每个流程实例的执行路径,等等。此服务主要通过查询功能来获得这些数据。
- ManagementService:Activiti的引擎管理类,提供了对 Activiti 流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于Activiti 系统的日常维护。
FormService:弃用,该管理类不符合 activiti 的设计理念。IdentityService:认证管理类,暂时不用。
2.5 数据库表
Activiti 流程框架有一套自己的数据库表,一共25张表,通过这些表从而实现流程管理。
这是官方数据库表的解释,文档适用于Activiti5~6:Activiti 数据库表结构
- ACT_RE_ : 'RE’表示repository,仓库的意思。 这个前缀的表包含了流程定义和流程静态资源
- ACT_RU_ :RU代表runtime,运行时的意思。这些是包含流程实例,用户任务,变量,作业等的运行时数据的运行时表。Activiti仅在流程实例执行期间存储运行时数据,并在进程实例结束时删除记录。这使得运行时间表保持不间断的快速。
- ACT_ID_ :ID代表identity,身份识别。这些表包含身份信息,如用户,组等。
- ACT_HI_ :HI代表history。这些是包含历史数据的表,例如过去的流程实例,变量,任务等。
- ACT_GE_ :general数据,用于各种用例。
2.6
3 入门配置工作
3.1 建个数据库,名字叫:activiti
3.2 创建一个 maven 项目,加入依赖
<properties>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<activiti.version>7.0.0.SR1</activiti.version>
</properties>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn 模型处理 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn 转换 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn json数据转换 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- bpmn 布局 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- activiti 云支持 -->
<dependency>
<groupId>org.activiti.cloud</groupId>
<artifactId>activiti-cloud-services-api</artifactId>
<version>7.0.0.Beta1</version>
<exclusions>
<exclusion><!-- 排除activiti的mybatis,避免和外面的mybatis-plus冲突 -->
<!-- 重点坑,不然启动项目会报错mybatisplus缺少类 -->
<artifactId>mybatis</artifactId>
<groupId>org.mybatis</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- 链接池 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
3.3 Activiti 配置文件 activiti.cfg.xml
<!--数据库连接池方式配置-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.1.181/activiti?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="test@xhkj"/>
<property name="maxActive" value="3"/>
<property name="maxIdle" value="1"/>
</bean>
<!--同样, 在默认方式下bean的id固定为 processEngineConfiguration-->
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!--引入上面配置好的 链接池-->
<property name="dataSource" ref="dataSource"/>
<property name="databaseSchemaUpdate" value="true"/>
</bean>
4 启动 Activiti
直接见代码,相关注释,代码里都很详细
package com.activiti.test;
import org.activiti.engine.*;
import org.junit.Test;
public class ActivitiCreate {
/**
* 使用activiti提供的默认方式来创建mysql的表
*/
@Test
public void testCreateDbTable1() {
// 需要使用avtiviti提供的工具类 ProcessEngines ,使用方法getDefaultProcessEngine
// getDefaultProcessEngine会默认从resources下读取名字为activiti.cfg.xml的文件
// 创建processEngine时,就会创建mysql的表
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println(processEngine);
}
@Test
public void testGetService() {
//获取各个service实例
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
HistoryService historyService = processEngine.getHistoryService();
}
/**
* 一般创建方式
*/
@Test
public void testCreateDbTable2() {
// ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
// 配置文件的名字可以自定义,bean的名字也可以自定义
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml","processEngineConfiguration");
// 获取流程引擎对象
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
}
}
5 简单运用 Activiti
直接见代码,相关注释,代码里都很详细
package com.activiti.test;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;
public class ActivitiDemo {
/**
* 流程部署
* `act_re_deployment` 流程部署表,每部署一次会增加一条记录
* `act_re_procdef` 流程定义表,张三会申请出差流程,李四也会申请出差流程,每个人申请都会增加一条记录
* act_re_deployment与act_re_procdef是一对多关系
* `act_ge_bytearray` 流程资源表,每个资源都会增加一条记录
*/
@Test
public void testDeployment() throws FileNotFoundException {
String evectionBpmnPath = ActivitiDemo.class.getClassLoader().getResource("bpmn/evection.bpmn").getFile();
File evectionBpmnFile = new File(evectionBpmnPath);
InputStream evectionBpmnIs = new FileInputStream(evectionBpmnFile);
String evectionPngPath = ActivitiDemo.class.getClassLoader().getResource("bpmn/evection.png").getFile();
File evectionPngFile = new File(evectionPngPath);
InputStream evectionPngIs = new FileInputStream(evectionPngFile);
// 1、创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3、使用service进行流程的部署,定义一个流程的名字,把bpmn和png部署到数据中
Deployment deploy = repositoryService.createDeployment()
.name("出差申请流程")
.addInputStream("evection.bpmn", evectionBpmnIs)
.addInputStream("evection.png", evectionPngIs)
.deploy();
// 4、输出部署信息
System.out.println("流程部署id=" + deploy.getId());
System.out.println("流程部署名字=" + deploy.getName());
}
/**
* 启动流程实例
* `act_hi_actinst` 流程实例执行历史信息
* `act_hi_identitylink` 流程参与用户的历史信息
* `act_hi_procinst` 流程实例的历史信息
* `act_hi_taskinst` 流程任务的历史信息
* `act_ru_execution` 流程执行信息
* `act_ru_identitylink` 流程的正在参与用户信息
* `act_ru_task` 流程当前任务信息
*/
@Test
public void testStartProcess() {
// 1、创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 3、根据流程定义的id启动流程
ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection");
// 4、输出内容
System.out.println("流程定义ID:" + instance.getProcessDefinitionId());
System.out.println("流程实例ID:" + instance.getId());
System.out.println("当前活动的ID:" + instance.getActivityId());
}
/**
* 查询个人待执行的任务
*/
@Test
public void testFindPersonalTaskList() {
// 1、获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取taskService
TaskService taskService = processEngine.getTaskService();
// 3、根据流程key 和 任务的负责人 查询任务
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("myEvection") //流程Key
.taskAssignee("李四") //要查询的负责人
.list();
// 4、输出
for (Task task : taskList) {
System.out.println("流程实例id=" + task.getProcessInstanceId());
System.out.println("任务Id=" + task.getId());
System.out.println("任务负责人=" + task.getAssignee());
System.out.println("任务名称=" + task.getName());
}
}
/**
* 完成个人任务 : 创建出差申请
* `act_ru_task` 这里的 '创建出差申请' 会变为 '经理审批'
* 也就是也是下一个任务: 经理审批
* `act_hi_taskinst` 这里的'创建出差申请'这条记录会有开始时间和结束时间
* 然后还会增加一条记录 '经理审批'
*/
@Test
public void completeTask() {
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
// 完成任务,参数:任务id,完成 '张三' 的任务
taskService.complete("2505");
}
// 改造: 不把id写死,通过查询,然后执行任务
// 完成经理'李四'的任务
@Test
public void completeTask2() {
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
// 完成 经理 '李四' 的任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("myEvection")
.taskAssignee("李四")
.singleResult();
System.out.println("流程实例id=" + task.getProcessInstanceId());
System.out.println("任务Id=" + task.getId());
System.out.println("任务负责人=" + task.getAssignee());
System.out.println("任务名称=" + task.getName());
taskService.complete(task.getId());
}
// 完成总经理'老马'的任务
@Test
public void completeTask3() {
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
// 完成 经理 '李四' 的任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("myEvection")
.taskAssignee("老马")
.singleResult();
System.out.println("流程实例id=" + task.getProcessInstanceId());
System.out.println("任务Id=" + task.getId());
System.out.println("任务负责人=" + task.getAssignee());
System.out.println("任务名称=" + task.getName());
taskService.complete(task.getId());
}
// 完成财务'小王'的任务
@Test
public void completeTask4() {
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
// 完成 经理 '李四' 的任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("myEvection")
.taskAssignee("小王")
.singleResult();
System.out.println("流程实例id=" + task.getProcessInstanceId());
System.out.println("任务Id=" + task.getId());
System.out.println("任务负责人=" + task.getAssignee());
System.out.println("任务名称=" + task.getName());
taskService.complete(task.getId());
}
// 如果一个流程中有多个任务,可以用list
@Test
public void completeTask5() {
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
// 完成 经理 '李四' 的任务
List<Task> tasks = taskService.createTaskQuery()
.processDefinitionKey("myEvection")
.taskAssignee("李四")
.list(); // 多个任务,用list
for (Task task : tasks) {
if (true) {
// 判断是哪任务
System.out.println("流程实例id=" + task.getProcessInstanceId());
System.out.println("任务Id=" + task.getId());
System.out.println("任务负责人=" + task.getAssignee());
System.out.println("任务名称=" + task.getName());
taskService.complete(task.getId());
}
}
}
}
(外链:以下是一整套Activiti7 的内容,有兴趣的可以看看)
- Activiti7 之工作流介绍(一):https://blog.csdn.net/qq_23845083/article/details/131292415
- Activiti7 之BPMN(二):https://mp.csdn.net/mp_blog/creation/success/131292515
- Activiti7 之新手入门(三):https://blog.csdn.net/qq_23845083/article/details/131292627
- Activiti7 之实战应用(四):https://blog.csdn.net/qq_23845083/article/details/131292700