参考:https://www.cnblogs.com/xine/p/14553069.html
参考:神思者老师的课程
文章目录
前言
在软件开发领域中,工作流自动化在简化业务流程和提高效率方面起着至关重要的作用。而在Java应用程序中实现工作流自动化的一个受欢迎选择就是Activiti,这是一个老牌的工作流引擎,能够与Spring Boot框架无缝集成。
在本文中,我们将深入探讨Activiti的特点、优势以及如何在Java项目中使用它来实现工作流自动化。
一、初识Activiti
1.什么是工作流?
在深入了解Activiti之前,让我们先来了解一下什么是工作流。简单来说,工作流是通过计算机协助实现流程自动化控制的一种方式。它主要解决的是在多个参与者之间按照预定义规则传递文档、信息或任务的过程,以实现特定的业务目标或推动目标的实现。
2.Activiti工作流引擎
Activiti是一个基于BPMN 2.0标准的开源工作流引擎。它允许我们自定义BPMN文件,其中声明了业务流程,并将这些BPMN文件交给Activiti引擎来执行。
BPMN文件实际上就是一个XML文件,其中使用不同的标签来定义不同的业务节点。例如:
- 如果是UserTask节点,工作流引擎在执行到该节点时会自动阻塞,并等待审批人员提供处理结果,然后才能继续执行流程。
- 如果遇到ServiceTask节点,通常会有与之对应的程序脚本。工作流引擎会自动执行这些程序脚本,完成ServiceTask任务,无需人工干预。
举个例子,我们可以定义一个ServiceTask脚本来自动生成Excel报表文件,并将其通过电子邮件发送给特定部门。这些操作都可以通过定义ServiceTask节点的脚本来实现,并由工作流引擎执行。
3.Activiti的优势
Activiti相对于其他Java领域的开源工作流产品,如Camunda和Flowable,更为简单和轻量级。它适用于小型项目和简单工作流。
与将业务流程硬编码到Java代码中相比,使用工作流引擎的优势在于维护方面。
- 当需要修改业务流程时,如果没有使用工作流引擎,我们需要修改Java代码,并重新编译和发布项目,这会非常麻烦。
- 而如果采用了工作流引擎,我们可以将具体业务流程从Java代码中分离出来,以XML文件的形式进行定义。这样,在重构流程时,除非是对流程进行大规模修改,我们几乎不需要重新修改Java代码,只需向Java程序提供新的XML文件即可。
此外,Activiti还支持JavaScript和Java等脚本语言。对于简单的计算、循环和判断等操作,我们可以使用JavaScript脚本来声明。而对于复杂的任务,我们可以定义Java任务类,并将其与ServiceTask节点关联起来。当工作流引擎执行到ServiceTask节点时,就会调用我们创建的Java任务类。
4.BPMN设计器
Activiti本身是一个强大的工作流引擎,但并不包含BPMN设计器。为了定义业务流程,我们需要安装一个BPMN设计器。过去,Eclipse上有一些BPMN设计器插件,但现在这些插件已经不再维护,无法使用。同样,IDEA上的BPMN插件也处于相同的状态,无法使用。
然而,现在有一些Web版本的BPMN设计器可供使用。我们可以通过浏览器访问官方网站,并选择快速开始,以开始使用这些设计器。这些Web版本的设计器通常具有直观的界面和丰富的功能,使我们能够轻松地定义和编辑BPMN流程。
然后就可以画工作流程了,如下:
二、SpringBoot项目整合Activiti
Activiti 7.0 是一个强大的工作流引擎,可以帮助我们自动化和管理业务流程。结合Spring Boot的灵活性和简洁性,我们可以创建强大且可扩展的应用程序。本文将展示如何将Activiti 7.0整合到Spring Boot项目中。
我们这里用的是Activiti7.0版本,Activiti7.0不支持1.8的JDK。所以必须是大于1.8的。
1.添加依赖
首先,在Spring Boot项目的pom.xml文件中添加以下依赖项,以引入Activiti 7.0:
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>7.0.0</version>
</dependency>
这将为项目提供Activiti 7.0的基本功能。
2.添加配置文件
首先添加Activiti的配置文件
activiti:
# 设置为true时,Activiti会自动更新数据库模式
database-schema-update: true
# 指定Activiti的历史级别为audit
historyLevel: audit
# 启用Activiti的数据库历史记录功能
db-history-used: true
这些是一些配置选项,用于配置Activiti在应用程序中的行为:
-
activiti.database-schema-update: true
: 这个选项指定了Activiti在启动时是否应该自动更新数据库模式。如果设置为true
,Activiti会根据需要自动创建或更新数据库表和索引。这对于开发和测试环境非常方便,但在生产环境中可能需要手动管理数据库模式的更新。 -
activiti.historyLevel: audit
:这个选项指定了Activiti的历史级别。历史级别定义了Activiti记录流程实例和任务历史数据的详细程度。audit
级别记录了最详细的历史数据,包括流程实例、任务、变量等的创建、更新和删除操作。 -
activiti.db-history-used: true
:这个选项指定了是否启用Activiti的数据库历史记录功能。如果设置为true
,Activiti会将历史数据存储在数据库中,以便后续查询和分析。如果设置为false
,则不会记录历史数据。
这些配置选项可以根据您的需求进行调整。确保根据环境和应用程序的要求进行适当的配置。
接下来在application.yml文件中,配置数据库连接信息。例如,如果使用的是MySQL数据库,可以添加以下配置:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/activiti??useSSL=false
username: root
password: your_password
确保将上述配置更改为适合您的数据库设置。
3.启动项目
如果项目启动没有任何报错信息,说明工作流项目就已经搭建成功了。
@SpringBootApplication
public class YourApplication {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}
三、使用Activiti工作流引擎进行开发
我们先用BPMN设计器去定义简单的工作流,然后交给Activiti引擎去执行,咱们体验一下工作流的部署和运行过程。Activiti兼容BPMN1.0和2.0规范,但是建议大家使用BPMN2.0来定义工作流程。
1.设计BPMN文件
在BPMN设计器上面参照下面的例子,拖拽生成一个工作流程。右侧是BPMN流程的ID和名称,然后必须设定成可执行的,否则Activiti无法运行这个BPMN文件。
上面BPMN流程中的两个服务节点是ServiceTask节点,属于不需要人工干预可以自动执行的节点。
定义好BPMN文件之后,我们选择下载XML格式的文档,方便我们格式化文档内容。
在IDEA项目中,新建bpmn目录,把下载的XML文件修改名字然后放进去。文件名称必须改成下面的后缀样式,甚至.XML这种大写的后缀都不可以。
打开这个XML文件,然后在里面的根标签上补上两个属性,只有这样做了,我们编辑这个文件才会有语法提示。结尾的BPMN20.xsd文字是红色的,并不是语法错误,不影响程序运行。
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:flowable="http://flowable.org/bpmn" id="diagram_Process_1700583687312"
targetNamespace="http://flowable.org/bpmn"
xmlns:activiti="http://activiti.org/bpmn"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
2.定义任务类
我们拖拽的服务节点属于ServiceTask,是会自动运行的,不需要人工干预。你想让这个节点执行什么功能,必须要声明Java类,把功能代码写到里面。
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
public class MyService_1 implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println("HelloWorld");
}
}
两个节点对应两个Java类,还得再创建一个:
public class MyService_2 implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println("你好世界");
}
}
接下来我们找到BPMN文件中的两个Task节点,让他们关联上Java类。
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:flowable="http://flowable.org/bpmn" id="diagram_Process_1700583687312"
targetNamespace="http://flowable.org/bpmn"
xmlns:activiti="http://activiti.org/bpmn"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="Process_1700583687312" name="业务流程_1700583687312" isExecutable="true">
<bpmn2:startEvent id="Event_0r7oy1l">
<bpmn2:extensionElements>
<flowable:formData/>
</bpmn2:extensionElements>
<bpmn2:outgoing>Flow_1wew4mh</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:serviceTask id="Activity_0daqsg0" name="服务任务1" flowable:exclusive="false" activiti:class="com.example.workflow.demo_1.MyService_1">
<bpmn2:incoming>Flow_1wew4mh</bpmn2:incoming>
<bpmn2:outgoing>Flow_0bhcxay</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:sequenceFlow id="Flow_1wew4mh" sourceRef="Event_0r7oy1l" targetRef="Activity_0daqsg0" />
<bpmn2:serviceTask id="Activity_0m4d7nx" name="服务任务2" activiti:class="com.example.workflow.demo_1.MyService_2">
<bpmn2:incoming>Flow_0bhcxay</bpmn2:incoming>
<bpmn2:outgoing>Flow_0zcquf0</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:sequenceFlow id="Flow_0bhcxay" sourceRef="Activity_0daqsg0" targetRef="Activity_0m4d7nx"/>
<bpmn2:endEvent id="Event_0r9j4v6">
<bpmn2:incoming>Flow_0zcquf0</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="Flow_0zcquf0" sourceRef="Activity_0m4d7nx" targetRef="Event_0r9j4v6"/>
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1700583687312">
<bpmndi:BPMNEdge id="Flow_1wew4mh_di" bpmnElement="Flow_1wew4mh">
<di:waypoint x="168" y="300"/>
<di:waypoint x="250" y="300"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0bhcxay_di" bpmnElement="Flow_0bhcxay">
<di:waypoint x="350" y="300"/>
<di:waypoint x="470" y="300"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0zcquf0_di" bpmnElement="Flow_0zcquf0">
<di:waypoint x="570" y="300"/>
<di:waypoint x="702" y="300"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Event_0r7oy1l_di" bpmnElement="Event_0r7oy1l">
<dc:Bounds x="132" y="282" width="36" height="36"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0daqsg0_di" bpmnElement="Activity_0daqsg0">
<dc:Bounds x="250" y="260" width="100" height="80"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_0r9j4v6_di" bpmnElement="Event_0r9j4v6">
<dc:Bounds x="702" y="282" width="36" height="36"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0m4d7nx_di" bpmnElement="Activity_0m4d7nx">
<dc:Bounds x="470" y="260" width="100" height="80"/>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
这是各个标签的含义:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 这是BPMN(Business Process Model and Notation)的XML定义文件。 -->
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:flowable="http://flowable.org/bpmn"
id="diagram_Process_1700583687312"
targetNamespace="http://flowable.org/bpmn"
xmlns:activiti="http://activiti.org/bpmn"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<!-- 这是流程定义 -->
<bpmn2:process id="Process_1700583687312" name="业务流程_1700583687312" isExecutable="true">
<!-- 开始事件 -->
<bpmn2:startEvent id="startEvent_1">
<!-- 在此处添加事件的详细信息 -->
</bpmn2:startEvent>
<!-- 服务任务 -->
<bpmn2:serviceTask id="serviceTask_1">
<!-- 在此处添加任务的详细信息 -->
</bpmn2:serviceTask>
<!-- 序列流 -->
<bpmn2:sequenceFlow id="sequenceFlow_1" sourceRef="startEvent_1" targetRef="serviceTask_1">
<!-- 在此处添加序列流的详细信息 -->
</bpmn2:sequenceFlow>
<!-- 结束事件 -->
<bpmn2:endEvent id="endEvent_1">
<!-- 在此处添加事件的详细信息 -->
</bpmn2:endEvent>
</bpmn2:process>
<!-- BPMN图形定义 -->
<bpmndi:BPMNDiagram>
<!-- BPMN平面 -->
<bpmndi:BPMNPlane>
<!-- 在此处添加流程图形状的详细信息 -->
</bpmndi:BPMNPlane>
<!-- BPMN边界 -->
<bpmndi:BPMNEdge>
<!-- 在此处添加流程图连线的详细信息 -->
</bpmndi:BPMNEdge>
<!-- BPMN形状 -->
<bpmndi:BPMNShape>
<!-- 在此处添加流程图元素的位置和大小的详细信息 -->
</bpmndi:BPMNShape>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
BPMN是一种用于描述业务流程的标准化符号和图形表示方法。XML文件中包含了流程定义的各个元素和它们之间的关系。
-
<bpmn2:process>
:这是流程的定义,包含了流程的各个元素。 -
id="Process_1700583687312"
:这是流程的唯一标识符。 -
name="业务流程_1700583687312"
:这是流程的名称。 -
isExecutable="true"
:指示流程是否可以执行。 -
<bpmn2:startEvent>
:这是开始事件,表示流程的起点。 -
<bpmn2:serviceTask>
:这是服务任务,表示流程中的一个具体操作。 -
<bpmn2:sequenceFlow>
:这是序列流,表示流程中的连线。 -
<bpmn2:endEvent>
:这是结束事件,表示流程的终点。 -
<bpmndi:BPMNDiagram>
:这是BPMN图形的定义。 -
<bpmndi:BPMNPlane>
:这是BPMN平面,包含了流程图的各个形状。 -
<bpmndi:BPMNEdge>
:这是BPMN边界,表示流程图中的连线。 -
<bpmndi:BPMNShape>
:这是BPMN形状,表示流程图中的元素的位置和大小。
通过这个XML文件,可以清楚地了解流程的定义和结构,以及各个元素之间的关系。
3.部署工作流
在SpringBoot项目中,Activiti会自动扫描processes目录下面的BPMN流程文件,然后部署到MySQL里面。我们创建的bpmn文件夹只是临时存放bpmn文件的,我们把编辑好的bpmn文件拷贝到processes目录,然后启动SpringBoot项目就自动部署了。
启动SpringBoot项目的时候,如果控制台输出了下面的提示信息,说明BPMN文件已经部署成功了。
4.运行工作流
在项目的test目录下的package中创建Demo_1.java测试类,编写Java代码运行工作流。在测试类中,你填写自己的工作流程name名称,不要原封不动的运行下面的代码。
import org.activiti.engine.RuntimeService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
public class Demo_1 {
@Resource
private RuntimeService runtimeService;
@Test
void run() {
runtimeService.startProcessInstanceByKey("Process_1700583687312").getProcessInstanceId();
}
}
测试类运行成功之后,在控制台你会看到输出的HelloWorld和你好世界,也就是说无需人为干预,只要Activiti执行工作流就会自动运行服务节点和任务类。
结论
通过将Activiti 7.0整合到您的Spring Boot项目中,您可以轻松地创建和管理业务流程。使用本文提供的步骤和技巧,您可以开始构建强大且可扩展的应用程序。祝您成功!