本文将介绍Activiti7基础概念及基于SpringBoot整合Activiti7的具体步骤。
作者:后端小肥肠
1. 前言
在企业级应用中,业务流程的管理和执行是至关重要的一环。Activiti7是一个强大的开源工作流引擎,它提供了灵活的流程定义、任务分配和执行监控功能。本篇博客将介绍Activiti7的相关概念,并详细讨论如何与Spring Boot整合。
2. Activiti7相关概念介绍
2.1. 什么是工作流
工作流的简单概念就是用于流程审批的。 如:请假审批流程、报销审批流程、出差审批流程 、合同审批流程等。 工作流(Workflow),就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目 标的实现"。 工作流引擎,主要是为了帮助我们实现流程自动化控制,对应的Activiti引擎就可以实现自动化控制。 工作流管理系统是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流规则进行工作流实例的执行。
2.2. 工作流应用场景
工作流应用场景:
业务类: 合同审批流程、订单处理流程、出入库审批流程等。
行政类: 请假流程、出差流程、用车流程、办公用品申请流程等。
财务类: 报销流程、支付流程等。
客户服务类: 售后跟踪、客户投诉等。
2.3. 什么是Activiti
Activiti 是由 jBPM (BPM,Business Process Management 即业务流程管理) 的创建者 Tom Baeyens 离开 JBoss 之后建立的项目,构建在开发 jBPM 版本 1 到 4 时积累的多年经验的基础之上,旨在创建下一代的 BPM 解决方案。
Activiti 是一个开源的工作流引擎,它实现了BPMN 2.0规范,可以发布设计好的流程定义,并通过api进行流程调 度。 Activiti 作为一个遵从 Apache 许可的工作流和业务流程管理开源平台,其核心是基于Java的超快速、超稳定的 BPMN2.0 流程引擎,强调流程服务的可嵌入性和可扩展性,同时更加强调面向业务人员。 Activiti 流程引擎重点关注在系统开发的易用性和轻量性上。每一项 BPM 业务功能 Activiti 流程引擎都以服务的形 式提供给开发人员。通过使用这些服务,开发人员能够构建出功能丰富、轻便且高效的 BPM 应用程序。
Activiti是一个针对企业用户、开发人员、系统管理员的轻量级工作流业务管理平台,其核心是使用Java开发的快 速、稳定的BPMN 2.0流程引擎。Activiti是在ApacheV2许可下发布的,可以运行在任何类型的Java程序中,例如服务器、集群、云服务等。Activiti可以完美地与Spring集成。同时,基于简约思想的设计使Activiti非常轻量级。
官网: https://www.activiti.org/
2.4. Activiti开发流程
- 画流程定义模型: 遵守BPMN的流程规范,使用BPMN的流程定义工具,通过流程符号把整个业务流程定义出来,可以将流程定义文件字节流保存到模型数据表中(Model);
- 部署流程定义: 加载画好的流程定义文件,将它转换成流程定义数(ProcessDefinition),保存到流程定义数据表中;
- 启动流程(提交流程申请): 生成流程实例数据(ProcessInstance),生成第1节点任务数据(Task);
- 处理人审批流程节点任务: 完成任务审批,生成审批结果,生成下一节点任务数据。
2.5. BPMN 2.0 规范是什么
业务流程模型注解(Business Process Modeling Notation-BPMN)是业务流程模型的一种标准图形注解。这个标准是由对象管理组(Object Management Group-OMG)维护的。
标准的早期版本(1.2版以及之前)仅仅限制在模型上, 目标是在所有的利益相关者之间形成通用的理解,在文档,讨论和实现业务流程之上。 BPMN标准证明了它自己,现在市场上许多建模工具都使用了BPMN标准中的元素和结构。BPMN规范的2.0版本,当前已经处于最终阶段了, 允许添加精确的技术细节在BPMN的图形和元素中,同时制定BPMN元素的执行语法。 通过使用XML语言来指定业务流程的可执行语法, BPMN规范已经演变为业务流程的语言,可 以执行在任何兼容BPMN2的流程引擎中, 同时依然可以使用强大的图形注解。
目前BPMN2.0是最新的版本,它用于在BPM上下文中进行布局和可视化的沟通。BPMN 2.0是使用一些符号来明确业务流程设计流程图的一整套符号规范,它能增进业务建模时的沟通效率。
2.6. BPMN 2.0 基本流程符号
事件 Event:
开始事件:
边界事件:
中间捕获事件:
结束事件:
活动 Activity:
活动是工作或任务的一个通用术语。一个活动可以是一个任务,还可以是一个当前流程的子处理流程; 其次,你还 可以为活动指定不同的类型。常见活动如下:
网关 Gateway:
排他网关 (x): 只有一条路径会被选择。流程执行到该网关时,按照输出流的顺序逐个计算,当条件的计算结果为true时,继续执行当前网关的输出流; 如果多条线路计算结果都是 true,则会执行第一个值为 true 的线路。如果所有网关计算结果没有true,则引擎会抛出异常。 排他网关需要和条件顺序流结合使用,default属性指定默认顺序流,当所有的条件不满足时会执行默认顺序流。
并行网关 (+) :所有路径会被同时选择。分支:并行执行所有输出顺序流,为每一条顺序流创建一个并行执行线路。 汇聚 :所有从并行网关拆分并执行完成的线路均在此等候,直到所有的线路都执行完成才继续向下执行。
包容网关 (o) : 可以同时执行多条线路,也可以在网关上设置条件。分支:计算每条线路上的表达式,当表达式计算结果为true时,创建一个并行线路并继续执行。 汇聚:所有从并行网关拆分并执行完成的线路均在此等候,直到所有的线路都执行完成才继续向下执行。
事件网关 (o+) : 专门为中间捕获事件设置的,允许设置多个输出流指向多个不同的中间捕获事件。当流程执行到事件网关后,流程处于等待状态,需要等待抛出事件才能将等待状态转换为活动状态。
定时器事件:
开始定时器事件: 可以设置时间,定时开始启动流程实例。
中间定时器事件: 设定延迟时间,当完成任务1后,到达延时时间,流程才会走向任务2。
边界定时器事件: 用于向某节点上添加边界定时事件。在设定时间内没有完成,流程实例则自动走向下一节点。
3. Spring Boot整合Activiti7简介
3.1. 开发环境搭建
3.1.1. 所用版本工具
依赖 | 版本 |
---|---|
Spring Boot | 2.5.0 |
activiti | 7.1.0.M5 |
MybatisPlus | 3.3.1 |
postgres | 13.12 |
3.1.2. pom依赖
js
<dependencies>
<!-- 依赖管理-->
<dependency>
<groupId>org.activiti.dependencies</groupId>
<artifactId>activiti-dependencies</artifactId>
<version>${activiti.version}</version>
<type>pom</type>
</dependency>
<!-- Activiti -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>${activiti.version}</version>
<!--上面用了mybatis-plus,要排除这个-->
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- java代码绘activiti流程图 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-image-generator</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- activiti json转换器-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- svn转换png图片工具 -->
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-all</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- web启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis-plus启动器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- swagger 接口文档-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.9.1.RELEASE</version>
</dependency>
<!-- springboot2.3.1后要单独引入,swagger才可以用 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
3.2. 整合流程模型设计器 Activiti Modele
Activiti 官方提供了 Web 版的流程设计工具 Activiti Modeler,可以直接整合到我们项目中。在 Activiti 5.10 版本把原本独立的 Activiti Modeler 模块整合到了 Activiti Explorer 模块中,两者相结合使用起来很方便, 通过 Modeler 设计的流程模型可以直接部署到引擎,也可以把已经部署的流程转换为Model从而在Modeler中编辑。 在实际应用中也有这样的需求,把 Modeler 整合到业务系统中可以供管理员使用,或者作为BPM流程管理平台的 一部分存在。 但是在 Activiti 官方没有给出如何整合Modeler的文档,要我们自己整合。
3.2.1. 下载源码
首先需要从 Github下载 Activiti 5.22 版本源码 访问: github.com/Activiti/Ac...
下载 zip 格式的压缩包: github.com/Activiti/Ac...
3.2.2. 拷贝目标源码
-
解压 Activiti-activiti-5.22.0.zip ,然后进入 Activiti-activiti-5.22.0/modules 目录。
-
复制 activiti-webapp-explorer2 工程中如下图画红框的文件夹和文件
粘贴到项目工程的 resources/static 目录下(static 目录创建)。
- 找到activiti-modeler工程下的3个类,如下:
拷贝到activiti包下(或者你自己命名的包):
3.2.3. 修改上下文路径
1.在项目工程中修改文件中上下文路径,这样才能请求到上面3 个接口
上下文路径对应 application.yml 文件中配置的 server.servlet.context-path=/workflow
3.2.4. 汉化 Activiti Modeler
汉化文件位于: download.csdn.net/download/c1...
-
汉化页面文字,在 resources/static/ 目录下添加 stencilset.json 文件。
-
需要修改 StencilsetRestResource.java 类中 stencilset.json 为 static/stencilset.json(最前面不要有/);
-
汉化按钮文字,添加zh-CN.json文件。在src/main/resources/static/editor-app/i18n目录下添加zh-CN.json文件。
- 修改src/main/resources/static/editor-app/app.js文件。将第51行替换为以下内容:
js
// $translateProvider.preferredLanguage('en');
// 多语言支持
if("zh-CN" == navigator.language){
$translateProvider.preferredLanguage('zh-CN');
}else {
$translateProvider.preferredLanguage('en');
}
启动项目时报错:
Error:Kotlin: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.16.
解决:重新编译下,然后再启动项目。
3.2.5. 创建空流程模型
- 创建一个 ModelController 模型控制器,用于创建空流程模型和跳转到模型设计页面 modeler.html
js
/**
* 模型设计控制层
*/
@Controller
@RequestMapping("/model")
public class ModelController {
@Autowired
RepositoryService repositoryService;
@Autowired
ObjectMapper objectMapper;
@GetMapping("/create") // /workflow/model/create
public void create(HttpServletRequest request, HttpServletResponse response) {
try {
String name = "请假流程模型";
String key = "leaveProcess";
String desc = "请输入描述信息......";
int version = 1;
// 1. 初始空的模型
Model model = repositoryService.newModel();
model.setName(name);
model.setKey(key);
model.setVersion(version);
// 封装模型json对象
ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put(ModelDataJsonConstants.MODEL_NAME, name);
objectNode.put(ModelDataJsonConstants.MODEL_REVISION, version);
objectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, desc);
model.setMetaInfo(objectNode.toString());
// 保存初始化的模型基本信息数据
repositoryService.saveModel(model);
// 封装模型对象基础数据json串
// {"id":"canvas","resourceId":"canvas","stencilset":{"namespace":"http://b3mn.org/stencilset/bpmn2.0#"},"properties":{"process_id":"未定义"}}
ObjectNode editorNode = objectMapper.createObjectNode();
ObjectNode stencilSetNode = objectMapper.createObjectNode();
stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
editorNode.replace("stencilset", stencilSetNode);
// 标识key
ObjectNode propertiesNode = objectMapper.createObjectNode();
propertiesNode.put("process_id", key);
editorNode.replace("properties", propertiesNode);
repositoryService.addModelEditorSource(model.getId(), editorNode.toString().getBytes("utf-8"));
response.sendRedirect(request.getContextPath() + "/modeler.html?modelId=" + model.getId());
// response.sendRedirect(request.getContextPath() + "/modeler.html?modelId=9fceea3b-c23b-11ed-b0a5-201e88269a86");
}catch (Exception e) {
e.printStackTrace();
}
}
}
-
重启mengxuegu-activiti-boot项目。
-
访问 http://localhost:8080/workflow/model/create , 会重定向到http://localhost:8080/workflow/modeler.html?modelId=xxxxxxxx
3.2.6. 绘制流程定义模型涉及表
ACT_RE_MODEL 流程模型基本信息表。
ACT_GE_BYTEARRAY 流程模型描述 json 串(注意不是xml串)和 流程图字节码。
4. 结语
本文对Activi7的相关概念进行了简要介绍,同时还对Spring Boot整合Activi7模型设计器的步骤进行了讲解,下期将以成品demo为例介绍基于Activiti7的工作流管理系统的实现,感兴趣的同学可动动你们发财的小手点点关注~