title: 一、Activiti7 概念和环境搭建
date: '2021-03-11 10:29:23'
updated: '2021-04-22 19:28:59'
tags: [Activiti7, 工作流]
permalink: /articles/2021/03/11/1615429763190.html
概念入门
首先来个定义,什么是工作流?
工作流(Workflow),指“业务过程的部分或整体在计算机应用环境下的自动化”。是对工作流程及其各操作步骤之间业务规则的抽象、概括描述。在计算机中,工作流属于计算机支持的协同工作(CSCW)的一部分。后者是普遍地研究一个群体如何在计算机的帮助下实现协同工作的。
工作流主要解决的主要问题是:为了实现某个业务目标,利用计算机在多个参与者之间按某种预定规则自动传递文档、信息或者任务。
看不懂?没关系,先来张图:
假设这是一张请假流程图,请假申请需要先提交给部门经理,部门经理同意后再转到总经理审核,部门经理没同意之前总经理是看不到这个请假申请的。
如果你是一个程序开发人员,想一想你会怎么开发这个系统?
通常情况下我们用许多的状态量来标识申请流程走到哪一步了。比如:
状态值 | 描述 |
---|---|
0 | 请假申请已提交 |
1 | 部门经理拒绝 |
2 | 部门经理同意,到总经理 |
3 | 总经理拒绝 |
4 | 总经理同意,下一步 |
。。。 | 。。。 |
很繁琐对吧?如果有多种流程,现有流程修改,任务量更会艰巨,所以,需要有一个工作流系统来帮助简化工作。
Activiti7就是这么一个工作流系统
可以这么理解:
Activiti对于工作流 相当于 Mysql对于关系型数据,前者的存在是为了更好的管理和使用后者。
当然,这是概念上的一些描述,事实上,Activiti就是一些jar包,它是使用Java语言开发的,用于简化,管理工作流开发的工作流引擎。
那Activity为什么能简化工作流开发呢?
在介绍Activiti之前,先来了解一下BPMN(Business Process Model and Notation),它是一种用来描述业务流程图的符号语言,类似于UML。
PS:BPMN相关的专业概念先不去看了,就像每个程序猿都会写SQL,但是四大范式,内模式,外模式那些专业概念不去看一时半会也说不上来,所以会用就行啦。
BPMN 是目前被各 BPM 厂商广泛接受的 BPM 标准。Activiti 就是使用 BPMN 2.0 进行流程建模、流程执行管理,它包括很多的建模符号,比如:
Event
用一个圆圈表示,它是流程中运行过程中发生的事情。
活动用圆角矩形表示,一个流程由一个活动或多个活动组成
Bpmn图形其实是通过xml表示业务流程,上边的.bpmn文件使用文本编辑器打开:
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="myProcess" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start">startEvent>
<userTask id="usertask1" name="创建请假单">userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1">sequenceFlow>
<userTask id="usertask2" name="部门经理审核">userTask>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2">sequenceFlow>
<userTask id="usertask3" name="人事复核">userTask>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3">sequenceFlow>
<endEvent id="endevent1" name="End">endEvent>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1">sequenceFlow>
process>
<bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
<bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="130.0" y="160.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="210.0" y="150.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="360.0" y="150.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="510.0" y="150.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="660.0" y="160.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="165.0" y="177.0">omgdi:waypoint>
<omgdi:waypoint x="210.0" y="177.0">omgdi:waypoint>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="315.0" y="177.0">omgdi:waypoint>
<omgdi:waypoint x="360.0" y="177.0">omgdi:waypoint>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="465.0" y="177.0">omgdi:waypoint>
<omgdi:waypoint x="510.0" y="177.0">omgdi:waypoint>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="615.0" y="177.0">omgdi:waypoint>
<omgdi:waypoint x="660.0" y="177.0">omgdi:waypoint>
bpmndi:BPMNEdge>
bpmndi:BPMNPlane>
bpmndi:BPMNDiagram>
definitions>
Activiti部署业务流程定义(.bpmn文件)。使用Activiti提供的api把流程定义内容存进数据库,在Activiti执行过程中可以查询定义的内容。
读者不要被这些符号,代码吓着了,接下来直接上手从代码层面感受一下Activiti的操作与便捷。
环境搭建
目前(2021年3月)Activiti最新版本是Activiti7
读者如果上网搜相关的学习教程,有些是基于Activiti 7.0.0.Beta1版本的,官方直接整合了Spring Boot,我们
直接按照官方教程来学习。
注意:Activiti 7 与Spring Security强耦合,无法排除,所以需要读者有Spring Security的知识
官方提供了很多入门示例https://github.com/Activiti/activiti-examples
一、导入依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.activiti.dependenciesgroupId>
<artifactId>activiti-dependenciesartifactId>
<version>7.1.0.M5version>
<scope>importscope>
<type>pomtype>
dependency>
dependencies>
dependencyManagement>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
Activiti的工作管理是通过25张表来实现的,所以这里需要引入数据库驱动
二、配置
添加数据库配置
spring
activiti
#1.flase:activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
#2.true: 默认值。activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
#3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
#4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
database-schema-updatetrue
#检测历史表是否存在
db-history-usedtrue
#记录历史等级 可配置的历史级别有none, activity, audit, full
history-level full
datasource
driver-class-name com.mysql.cj.jdbc.Driver
url jdbc mysql //localhost 3306/activiti7?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
username root
password123456
三、编写测试代码
Activiti将之前的底层API抽象成了TaskRuntime和ProcessRuntime,简化了操作。但是,之前说过Activiti与Spring Security强耦合,在使用这两个API之前,要求具有ACTIVITI_USER角色的用户必须已经登录。
在官方示例中给出了两个工具类:
引入这两个工具类
四、编写测试类
public class Test {
private SecurityUtil securityUtil;
private TaskRuntime taskRuntime;
public void test14() {
// 什么都不用做,只要登录就好了
securityUtil.logInAs("salaboy");
}
}
目录结构这个样子:
注意注意注意,运行测试后,应该可能一定会出现这个问题:
### Error updating database. Cause: java.sql.SQLSyntaxErrorException: Unknown column 'VERSION_' in 'field list'
### The error may exist in org/activiti/db/mapping/entity/Deployment.xml
### The error may involve org.activiti.engine.impl.persistence.entity.DeploymentEntityImpl.insertDeployment-Inline
### The error occurred while setting parameters
### SQL: insert into ACT_RE_DEPLOYMENT(ID_, NAME_, CATEGORY_, KEY_, TENANT_ID_, DEPLOY_TIME_, ENGINE_VERSION_, VERSION_, PROJECT_RELEASE_VERSION_) values(?, ?, ?, ?, ?, ?, ?, ?, ?)
### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'VERSION_' in 'field list'
简直神坑,目前还没有好的办法,只能手动修改ACT_RE_DEPLOYMENT表,添加VERSION,PROJECT_RELEASE_VERSION这两个字段**。
总共会生成25张表
表分类 | 表名 | 解释 |
---|---|---|
一般数据 | ||
[ACT_GE_BYTEARRAY] | 通用的流程定义和流程资源 | |
[ACT_GE_PROPERTY] | 系统相关属性 | |
流程历史记录 | ||
[ACT_HI_ACTINST] | 历史的流程实例 | |
[ACT_HI_ATTACHMENT] | 历史的流程附件 | |
[ACT_HI_COMMENT] | 历史的说明性信息 | |
[ACT_HI_DETAIL] | 历史的流程运行中的细节信息 | |
[ACT_HI_IDENTITYLINK] | 历史的流程运行过程中用户关系 | |
[ACT_HI_PROCINST] | 历史的流程实例 | |
[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] | 运行时变量表 |
现在环境已经搭建好了,先写到这,相关API的操作下次再介绍。