目录
文章目录
- 目录
- 准备Activiti建模工具
-
- 1、BPMN-js在线设计器
-
- [1.1 安装](#1.1 安装)
- [1.2 使用说明](#1.2 使用说明)
- 1.3运行截图
- [2、IDEA安装Activiti Designer插件](#2、IDEA安装Activiti Designer插件)
-
- 2.1安装插件
- [2.2 设置编码格式防止中文乱码](#2.2 设置编码格式防止中文乱码)
- [2.3 截图](#2.3 截图)
- 简单工作流入门实例
准备Activiti建模工具
这里可以使用两种建模工具:bpmn.js和 IDEA的插件
1、BPMN-js在线设计器
bpmn.js是一个BPMN2.0渲染工具包和web建模器。
1.1 安装
需要使用到nodejs环境
1.1. 1 切换到项目目录下运行 npm install 安装依赖,也可以使用
bash
cnpm install
1.1.2. 运行 npm run dev 启动
bash
npm run dev
1.2 使用说明
可在页面进行拖拽设计 activiti 的流程图,支持导出 bpmn 流程图和 svg 图片
1.3运行截图
2、IDEA安装Activiti Designer插件
2.1安装插件
在IDEA的File菜单中找到子菜单"Settings",后面我们再选择左侧的"plugins"菜单,搜索actiBPM插件。
重启IDEA就可以使用了。
2.2 设置编码格式防止中文乱码
更改idea配置文件, 否则工作流中输入中文会乱码
- 进入idea安装目录的bin文件夹下, 找到idea.exe.vmoptions与idea64.exe.vmoptions两个文件
- 在两个文件的最后加入 -Dfile.encoding=UTF-8
2.3 截图
简单工作流入门实例
这里使用 SpringBoot+Activiti 实现一个最基础的工作流
1. 新建Spring Boot工程
打开IDEA创建一个SpringBoot项目
输入组织名,包名,打包方式jar,创建Maven项目,java版本8
选择要使用的组件,你可以在这里选择自己需要的,在生成最终的项目时会自动加入到maven中。
2. 引入Activiti相关依赖
添加版本属性
bash
<properties>
<java.version>1.8</java.version>
<activiti.version>7.1.0.M6</activiti.version>
</properties>
声明依赖版本
<!-- 声明依赖-->
<dependencyManagement>
<dependencies>
<!-- 声明activiti依赖的版本-->
<dependency>
<groupId>org.activiti.dependencies</groupId>
<artifactId>activiti-dependencies</artifactId>
<version>${activiti.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
指定仓库
添加私服仓库地址,不然容易出现无法下载包的问题
bash
<!--指定仓库-->
<repositories>
<!-- activiti仓库 -->
<repository>
<id>alfresco</id>
<name>Activiti Releases</name>
<url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
添加依赖
xnl
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
</dependency>
完整的pom文件
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ts</groupId>
<artifactId>springboot_activiti_demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot_activiti_demo</name>
<description>Spring Boot + Activiti实例</description>
<properties>
<java.version>1.8</java.version>
<activiti.version>7.1.0.M6</activiti.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- 生成图片 -->
<!--<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-image-generator</artifactId>
</dependency>-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
<scope>runtime</scope>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!-- Thymeleaf依赖 -->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--指定仓库-->
<repositories>
<!-- activiti仓库 -->
<repository>
<id>alfresco</id>
<name>Activiti Releases</name>
<url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<!-- 声明依赖-->
<dependencyManagement>
<dependencies>
<!-- 声明activiti依赖的版本-->
<!--<dependency>
<groupId>org.activiti.dependencies</groupId>
<artifactId>activiti-dependencies</artifactId>
<version>${activiti.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>-->
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.配置数据库
添加MySQL依赖
在正常使用中,一般系统会有自己的数据库,而不会采用Activiti默认内存的数据库H2,这里使用MySQL数据库。
bash
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
<scope>runtime</scope>
</dependency>
修改配置文件
修改application.yml文件
bash
spring :
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC&nullCatalogMeansCurrent=true
#url: jdbc:mysql://127.0.0.1:3306/activiti?useUnicode=true&characterEncoding=utf-8&serverTimezone=CTT&useSSL=false
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
initialization-mode: always
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
Activiti相关配置
修改application.yml文件
activiti:
# 自动建表
#database-schema: activiti
database-schema-update: true
history-level: full
db-history-used: true
database-schema-update表示启动时检查数据库表,不存在则创建
history-level表示哪种情况下使用历史表,这里配置为full表示全部记录历史,方便绘制流程图
db-history-used为true表示使用历史表,如果不配置,历史表没有建立,则流程图及运行节点无法展示
4.配置application.yml文件清单
bash
spring :
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/testactiviti?useUnicode=true&characterEncoding=utf-8&serverTimezone=CTT&useSSL=false
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
initialization-mode: always
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
# mvc:
# 静态资源
# static-path-pattern: /static/**
# thymeleaf:
# mode: HTML
# encoding: utf-8
# #关闭缓存
# cache: false
activiti:
#1.flase: 默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
#2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
#3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
#4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
database-schema-update: true
#记录历史等级 可配置的历史级别有none, activity, audit, full
history-level: full
#检测历史表是否存在
db-history-used: true
#校验流程文件,默认校验resources下的processes文件夹里的流程文件
check-process-definitions: false
4启动SpringBoot
启动SpringBoot工程,生成表(25张)
5.新建流程
创建bpmn工作流文件
首先选中存放图形的目录(选择resources下的bpmn目录),点击菜单:New-BpmnFile
绘制流程
绘制完成以后修改id和name,然后指定任务负责人
生成png图像
复制bpmn_test.bpmn并更名bpmn_test.xml
右键选中Diagrams--》show BPMN2.0
点击Export to file ,然后放在resources下的bpmn目录下就可以了。
部署工作流程
要将上边绘制的图形即流程定义(.bpmn)部署在工作流程引擎activiti中
创建一个测试类ActivitiTest
bash
package com.ts;
//import org.activiti.api.process.runtime.ProcessRuntime;
//import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* 流程测试类
* @author ZQ
* @date 2020/11/23 0019 15:16
**/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiTest {
//@Autowired
//private ProcessRuntime processRuntime;
//@Autowired
//private ProcessEngine processEngine;
@Autowired
private RepositoryService repositoryService;
private static final Logger log = LoggerFactory.getLogger(ActivitiTest.class);
/**
* 流程定义的部署
* activiti相关表
* act_re_deployment 部署信息
* act_re_procdef 流程定义的一些信息
* act_ge_bytearray 流程定义的bpmn文件及png文件
*/
@Test
public void createDeploy() {
//RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("bpmn/bpmn_test.bpmn")//添加bpmn资源
.addClasspathResource("bpmn/bpmn_test.png")
.name("请假申请单流程")
.deploy();
log.info("流程部署id:" + deployment.getName());
log.info("流程部署名称:" + deployment.getId());
}
}
执行此操作后activiti会将上边代码中指定的bpm文件和图片文件保存在activiti数据库。
启动一个流程实例
流程定义部署在activiti后就可以通过工作流管理业务流程了,也就是说上边部署的请假申请流程可以使用了。
针对该流程,启动一个流程表示发起一个新的请假申请单,这就相当于java类与java对象的关系,类定义好后需要new创建一个对象使用,当然可以new多个对象。
对于请假申请流程,张三发起一个请假申请单需要启动一个流程实例,李四发起一个请假单也需要启动一个流程实例。
bash
/**
* 2
* 启动流程实例:
* 前提是先已经完成流程定义的部署工作
* <p>
* 背后影响的表:
* act_hi_actinst 已完成的活动信息
* act_hi_identitylink 参与者信息
* act_hi_procinst 流程实例
* act_hi_taskinst 任务实例
* act_ru_execution 执行表
* act_ru_identitylink 参与者信息
* act_ru_task 任务
*/
@Test
public void startProcessInstance() {
RuntimeService runtimeService = processEngine.getRuntimeService();
//启动流程实例
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("myProcess_1");//这里的key就是流程图的ID
log.info("流程定义ID:" + processInstance.getProcessDefinitionId());
log.info("流程实例ID:" + processInstance.getId());
}
任务查询
流程启动后,各各任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。
bash
/**
* 3
* 查询当前用户的任务列表
*/
@Test
public void findPersonalTaskList() {
TaskService taskService = processEngine.getTaskService();
//流程启动后,各各任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。
//根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
List<Task> taskList = taskService.createTaskQuery()
//流程实例key
.processDefinitionKey("myProcess_1")
//查询谁的任务
.taskAssignee("张三")
.list();
for (Task task : taskList) {
System.out.println("-----------------------");
System.out.println("流程实例ID:" + task.getProcessInstanceId());
System.out.println("执行对象ID:" + task.getExecutionId ());
System.out.println("流程定义ID:" + task.getProcessDefinitionId ());
System.out.println("任务ID:" + task.getId());
System.out.println("任务名称:" + task.getName());
System.out.println("任务负责人:" + task.getAssignee());
System.out.println("任务的创建时间:" + task.getCreateTime ());
}
}
任务处理
任务负责人查询待办任务,选择任务进行处理,完成任务。
bash
/**
* 3
* 处理当前用户的任务
* 背后操作的表:
* act_hi_actinst
* act_hi_identitylink
* act_hi_taskinst
* act_ru_identitylink
* act_ru_task
*/
@Test
public void completeTask() {
String processDefinitionKey = "myProcess_1";
TaskService taskService = processEngine.getTaskService();
//查询任务
Task task = taskService
.createTaskQuery()
.processDefinitionKey(processDefinitionKey)
.taskAssignee("张三")
.singleResult();
if(task != null){
//处理任务,结合当前用户任务列表的查询操作的话
taskService.complete(task.getId());
log.info("处理完成当前用户的任务");
}else{
log.info("当前用户暂无任务");
}
}
查询历史
bash
/*
* 查询历史
* @author zq
* @param *[]
* @return void
**/
@Test
public void queryHistory() {
HistoryService historyService = processEngine.getHistoryService();
RepositoryService repositoryService = processEngine.getRepositoryService();
//查询流程定义
ProcessDefinitionQuery processDefinitionQuery =
repositoryService.createProcessDefinitionQuery();
String processDefinitionKey = "myProcess_1";
//遍历查询结果
ProcessDefinition processDefinition =
processDefinitionQuery
.processDefinitionKey(processDefinitionKey)
.orderByProcessDefinitionVersion().desc().singleResult();
if (processDefinition != null) {
HistoricActivityInstanceQuery query = historyService
.createHistoricActivityInstanceQuery();
List<HistoricActivityInstance> list =
query.processDefinitionId(processDefinition.getId())
.orderByHistoricActivityInstanceStartTime().asc().list();//排序StartTime
for (HistoricActivityInstance ai : list) {
System.out.println("历史活动ID:" + ai.getActivityId());
System.out.println("历史活动Name:" + ai.getActivityName());
System.out.println("流程定义ID" + ai.getProcessDefinitionId());
System.out.println("流程实例ID" + ai.getProcessInstanceId());
System.out.println("==============================");
}
}
}
执行结果