SpringBoot+Activiti7工作流入门实例

目录

文章目录

准备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配置文件, 否则工作流中输入中文会乱码

  1. 进入idea安装目录的bin文件夹下, 找到idea.exe.vmoptions与idea64.exe.vmoptions两个文件
  2. 在两个文件的最后加入 -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("==============================");
        }
    }
}

执行结果

相关推荐
天使day3 分钟前
SpringMVC
java·spring·java-ee
计算机学长felix8 分钟前
基于SpringBoot的“旅游管理系统”的设计与实现(源码+数据库+文档+PPT)
spring boot·毕业设计
CodeClimb21 分钟前
【华为OD-E卷-简单的自动曝光 100分(python、java、c++、js、c)】
java·python·华为od
风清云淡_A32 分钟前
【java基础系列】实现数字的首位交换算法
java·算法
Gao_xu_sheng34 分钟前
Java程序打包成exe,无Java环境也能运行
java·开发语言
大卫小东(Sheldon)41 分钟前
Java的HTTP接口测试框架Gatling
java
谢家小布柔42 分钟前
java中的继承
java·开发语言
l138494274511 小时前
Java每日一题(2)
java·开发语言·游戏
苹果醋31 小时前
SpringBoot快速入门
java·运维·spring boot·mysql·nginx
WANGWUSAN661 小时前
Python高频写法总结!
java·linux·开发语言·数据库·经验分享·python·编程