Activiti 环境搭建及部署

2021/12/13 Activi

# 1、资料地址

# 2、插件安装(idea)

插件是为了方便在开发工具中查看和修改流程图

# 2.1 离线安装

  • 插件地址:https://github.com/valb3r/flowable-bpmn-intellij-plugin/releases/
  • 下载activiti-bpmn-plugin.zip
  • File -> Settings -> Plugins -> 【小齿轮图标】-> Install Plugin from Dist...

# 2.2 在线安装

  • File -> Settings -> Plugins:搜索Activiti BPMN visualizer
  • 安装

# 2.3 常见问题

问:我的 Activiti/Flowable 引擎文件有.bpmn扩展名而不是bpmn20.xml,我该如何打开它们。
A:导航到 文件>设置>工具> Activiti BPMN 插件配置(或Flowable BPMN 插件配置)。 在字段Supported extensions add 中bpmn,该字段值为bpmn20.xml,bpmn. 现在你应该可以打开它了。

# 3、环境搭建及准备

不做某框架的集成,只做最简单的代码演示使用,先按照以下步骤操作,能运行看到结果后再去了解代码含义和数据库对应关系

# 3.1 创建最简单的一个maven项目

  • File -> New -> Project -> Maven -> next
  • 填写maven坐标信息 -> Finish

# 3.2 引入依赖包

修改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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>top.biupia</groupId>
    <artifactId>ActivitiDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <activiti-version>6.0.0</activiti-version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </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>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.6</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.7.6</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- Mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

# 3.3 数据库配置文件

在resources下创建activiti.cfg.xml,并填写一下内容

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
	<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
		<!-- 连接数据的配置 -->
		<property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8&amp;zeroDateTimeBehavior=convertToNull&amp;useSSL=true&amp;serverTimezone=GMT%2B8&amp;nullCatalogMeansCurrent=true"></property>
		<property name="jdbcUsername" value="root"></property>
		<property name="jdbcPassword" value="root"></property>
		<!-- 没有表创建表,可以在代码中配置 -->
        <!--<property name="databaseSchemaUpdate" value="true"></property>-->
	</bean>
</beans>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 3.4 编写流程图

在resources下创建diagrams文件夹(可省略),然后再文件夹下创建HelloWorld.bpmn文件,并填写一下内容

<?xml version="1.0" encoding="UTF-8"?>
<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="helloworld" name="helloworldProcess" isExecutable="true">
    <startEvent id="startevent1" name="Start"/>
    <endEvent id="endevent1" name="End"/>
    <userTask id="usertask1" name="提交申请" activiti:assignee="依依"/>
    <userTask id="usertask2" name="审批【部门经理审批】" activiti:assignee="尔康"/>
    <userTask id="usertask3" name="审核【总经理审批】" activiti:assignee="三叔"/>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"/>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"/>
    <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"/>
    <sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"/>

  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_helloworld">
    <bpmndi:BPMNPlane bpmnElement="helloworld" id="BPMNPlane_helloworld">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="840.00006" y="75.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="840.0" y="575.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="805.0" y="185.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
        <omgdc:Bounds height="55.0" width="130.0" x="793.0" y="315.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
        <omgdc:Bounds height="55.0" width="130.0" x="798.0" y="446.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="857.00006" y="110.0"/>
        <omgdi:waypoint x="857.0" y="185.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="857.0" y="240.0"/>
        <omgdi:waypoint x="858.0" y="315.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="858.0" y="370.0"/>
        <omgdi:waypoint x="858.0" y="446.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="858.0" y="501.0"/>
        <omgdi:waypoint x="857.0" y="575.0"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

在该文件上鼠标右击或者在该文件打开的视图中鼠标右击,如下图所示 生成流程图图片,在打开的流程图界面中右键然后选在保存图片,如下图所以

# 3.5 代码及数据库初始化

数据库通过代码直接生成,按照流程图使用流程,代码部分分为以下几个测试代码

  • 1、数据库初始化
  • 2、部署流程
  • 3、查询流程
  • 4、启动流程实例
  • 5、查询流程实例
  • 6、完成流程任务

代码结构如图及主要java代码如下

package top.biupia;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.util.List;

/**
 * description: HelloWorld <br>
 * date: 2021/12/14 17:11 <br>
 * author: fuyd <br>
 */
public class HelloWorld {
    /**
     * 内部实现调用resources = classLoader.getResources("activiti.cfg.xml");加载数据库配置,所以配置一个activiti.cfg.xml文件即可使用
     */
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    // 初始化数据库表
    @Test
    public void init() {
        // 获得引擎配置,可以修改配置完成自己想要的操作
        ProcessEngineConfiguration processEngineConfiguration = processEngine.getProcessEngineConfiguration();

        /**
         * public static final String DB_SCHEMA_UPDATE_FALSE = "false";不能自动创建表,需要表存在
         * public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";先删除表再创建表
         *
         * 使用下面的配置,完成自动创建表,在xml中直接使用后面的值
         * public static final String DB_SCHEMA_UPDATE_TRUE = "true";如果表不存在,自动创建表
         */
        processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
    }

    /**
     * 部署流程定义
     */
    @Test
    public void deploymentProcessDefinition() {
        // RepositoryService 与流程定义和部署对象相关的Service
        Deployment deployment = processEngine.getRepositoryService()
                //创建一个部署对象
                .createDeployment()
                //添加部署的名称
                .name("部署流程")
                //从classpath的资源中加载,一次只能加载一个文件
                .addClasspathResource("diagrams/HelloWorld.bpmn")
                //从classpath的资源中加载,一次只能加载一个文件
                .addClasspathResource("diagrams/HelloWorld.png")
                //完成部署
                .deploy();
        /**
         * 部署流程后,会在 act_re_deployment、act_re_procdef、act_ge_bytearray表中添加数据;
         * act_re_deployment  部署对象表
         * act_re_procdef     流程定义表
         * act_ge_bytearray   二进制数据表,存储通用的流程定义和流程资源
         *
         * act_ge_property    系统相关属性,属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录。
         */
        System.out.println("部署ID:" + deployment.getId());
        System.out.println("部署名称:" + deployment.getName());
    }

    /**
     * 查询流程定义构造器
     */
    @Test
    public void findProcess() {
        // 流程定义和部署相关服务类
        List<ProcessDefinition> list = processEngine.getRepositoryService()
                //流程定义查询
                .createProcessDefinitionQuery()
               // //act_re_procdef.DEPLOYMENT_ID_
               // .deploymentId("1")
               // //act_re_procdef.KEY_
               // .processDefinitionKey("helloworld")
               // //act_re_procdef.NAME_
               // .processDefinitionName("helloworldProcess")
               // //act_re_procdef.ID_
               // .processDefinitionId("helloworld:1:4")
                //单条数据
                //.singleResult()
                .list();
        for (ProcessDefinition processDefinition : list) {
            //act_re_procdef.DEPLOYMENT_ID_  部署流程的ID (对应act_re_deployment表ID)
            System.out.println("dep:" + processDefinition.getDeploymentId());
            //act_re_procdef.KEY_
            System.out.println("Key:" + processDefinition.getKey());
            //act_re_procdef.NAME_
            System.out.println("Name:" + processDefinition.getName());
            //act_re_procdef.ID_  act_re_procdef主键ID
            System.out.println("ID:" + processDefinition.getId());
        }
    }

    /**
     * 启动流程实例
     */
    @Test
    public void startProcessInstance() {
        // RuntimeService 启动流程service
        //流程定义的key
        String processDefinitionKey = "helloworld";
        //与正在执行的流程实例和执行对象相关的Service
        ProcessInstance pi = processEngine.getRuntimeService()
                //使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
                .startProcessInstanceByKey(processDefinitionKey);
        //流程实例ID    格式如:101
        System.out.println("流程实例ID:" + pi.getId());
        //流程定义ID   格式如:helloworld:1:4
        System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
    }

    /**
     * 查询当前人的个人任务
     */
    @Test
    public void findMyPersonalTask() {
        String assignee = "依依";// 尔康,三叔;在流程图中查看activiti:assignee对应的值即可

        //与正在执行的任务管理相关的Service:TaskService
        List<Task> list = processEngine.getTaskService()
                //创建任务查询对象
                .createTaskQuery()
                //指定个人任务查询,指定办理人
                .taskAssignee(assignee)
                //获取查询列表
                .list();

        // 输出数据
        list.forEach(task -> {
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("任务的创建时间:" + task.getCreateTime());
            System.out.println("任务的办理人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
            System.out.println("执行对象ID:" + task.getExecutionId());
            System.out.println("流程定义ID:" + task.getProcessDefinitionId());
        });
    }

    /**
     * 完成我的任务
     */
    @Test
    public void completeMyPersonalTask() {
        //任务ID
        String taskId = "302";

        //与正在执行的任务管理相关的Service
        processEngine.getTaskService()
                .complete(taskId);

        System.out.println("完成任务:任务ID:" + taskId);
    }

    /**
     * 删除流程,执行该测试用例后数据库会清空
     */
    @Test
    public void delete() {
        List<ProcessDefinition> list = processEngine.getRepositoryService().createProcessDefinitionQuery().list();

        list.forEach(t -> {
            // Deletes the given deployment and cascade deletion to process instances, history process instances and jobs.
            // 删除给定流程部署定义(deployment),并且级联删除掉process instances, history process instances and jobs
            // 如果cascade参数为false,那么就不会级联删除
            processEngine.getRepositoryService().deleteDeployment(t.getDeploymentId(), true);
        });

        System.out.println(processEngine.getRepositoryService().createProcessDefinitionQuery().count());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
留言:
    更新日期: 2022/2/8 下午11:10:51