在Springboot集成Activiti工作流引擎-引入、调用,测试【基础讲解】-程序员宅基地

技术标签: 工作流  spring boot  java  Activiti  后端  

工作流 通过计算机对业务流程自动化执行管理
他主要解决的是使在多个参与者之间按照某种“预定义规则”自动进行传递稳定 信息或任务的过程
通俗来讲 业务上一个玩着的审批流程 比如请假,出差 外出采购等

工作流引擎就是来解决流程问题的 提高我们的工作效率

如果没有工作流引擎 我们就需要自己去写逻辑 就特别的复杂 扩展性还不强

使用工作流引擎 业务改变,不需要修改代码
如果是我们自己写的逻辑 有可能 业务改变,代码也需要改变

那么为什么工作流引擎不用修改代码
因为我们的工作流引擎都实现了一个规范
这个规范要求我们的流程管理与状态字段无关,始终都是读取业务流程图的下一个节点
当业务发生改变我们只需要更新业务流程图即可

常见的工作流引擎有
Activiti、jBPM、Camunda、Flowable 还有我们国产的盘古BPM、云程

https://www.activiti.org/ 官网地址

建模语言BPMN
BPM 意思就是 业务流程管理,
BPM 软件根据企业中业务环节的变化,推进人与人之间,人与系统之间以及系统与系统之间的整理及调整的经营方法和解决方案的IT工具

BPMN 意思就是 业务流程模型和符号,是一套标准的业务流程建模符号 Activiti就是使用BPMN 进行流程建模和流程执行管理

事件 Event

开始 表示一个流程的开始
中间 发生的开始和结束事件之间,影响处理流程
结束 表示该过程结束
在这里插入图片描述

活动 Activities

活动是工作或任务的一个通用术语,一个活动也可以是一个任务还是可以是一个当前流程的子处理流程
其次 你还可以为活动指定不同的类型
比如
用户任务-> 服务任务-> 子流程
在这里插入图片描述

网关 GateWay

用于表示流程的分支与合并
排他网关 并行网关 包容网关 综合网关 事件网关

在这里插入图片描述

排他网关 只有一条路径会被选择
并行网关 所有路径都会被同时选择
包容网关 可以同时执行多条线路,也可以在网关上设置条件
事件网关 专门为中间捕获事件设置的,允许设置多个输出流指向多个不同的中间捕获事件
当流程执行到事件网关后,流程处于等待状态,需要等抛出事件才能将等待状态转换为活动状态

在这里插入图片描述

流向 Flow
流是连接两个流程节点的连线
顺序流:用一个带实心箭头的实心线表示,用于指定活动执行顺序
信息流:用一条带箭头的虚线表示,用于描述两个独立的业务参与者之间发送和接受的消息流动
关联: 用一根带有线箭头的点线表示,用于将相关的数据,文本,和其他人工信息与流对象联系起来
用于展示活动的输入和输出

在这里插入图片描述

Activiti的使用流程

第一步 引入依赖并初始化数据库
引入依赖

第二步 通过工具绘画流程图
通过Activiti流程建模工具定义业务流程 生成(.bpmn文件)
.bpmn文件就是业务流程定义文件 通过xml定义业务流程

第三步 流程定义部署
向Activiti部署业务流程定义(.bpmn文件) 使用Activiti提供的api向Activiti中部署.bpmn文件
通俗一点就是 让Activiti认识要使用的流程

第四步 启动一个流程实例
启动一个流程实例表示开始一次业务流程的运行

第五步 用户查询代办任务
因为现在流程的业务交给了Activiti管理 通过Activiti就可以查询当前流程执行到那里了
当前用户需要执行什么任务 这些Activiti都会帮我们管理
我们学习了Activiti的API 就可以了

第六步 用户办理任务
用户查询代办任务后,就可以办理某个任务,如果这个任务办理还需要其他用户办理,也不需要我们写代码
Activiti 帮我们完成了

第七步 流程结束

Activiti 数据库支持 mysql 等

项目使用

第一步 引入依赖

    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-spring-boot-starter</artifactId>
        <version>7.1.0.M6</version>
        <exclusions>
            <exclusion>
                <artifactId>mybatis</artifactId>
                <groupId>org.mybatis</groupId>
            </exclusion>
        </exclusions>
    </dependency>

activiti 默认集成了Security 安全框架,当前我们项目里已经集成了Security 后续设置审批人必须是系统用户
否则会报错

第二步 添加配置

spring
   activiti:
     #    false:默认,数据库表不变,但是如果版本不对或者缺失表会抛出异常(生产使用)
     #    true:表不存在,自动创建(开发使用)
     #    create_drop: 启动时创建,关闭时删除表(测试使用)
     #    drop_create: 启动时删除表,在创建表 (不需要手动关闭引擎)
     database-schema-update: true
     #监测历史表是否存在,activities7默认不开启历史表
     db-history-used: true
     #none:不保存任何历史数据,流程中这是最高效的
     #activity:只保存流程实例和流程行为
     #audit:除了activity,还保存全部的流程任务以及其属性,audit为history默认值
     #full:除了audit、还保存其他全部流程相关的细节数据,包括一些流程参数
     history-level: full
     #校验流程文件,默认校验resources下的process 文件夹的流程文件
     check-process-definitions: true

第三步:启动项目后 如果表不存在 会自动创建

表介绍
act_re re表示repository 这个前缀包含了定义和流程静态资源
act_ru ru表示runtime 表示表运行时
act_hi hi表示history 历史数据
act_ge ge表示general 通用数据
在这里插入图片描述
在这里插入图片描述

第四步 activiti 设计工具

官网下载地址
https://www.activiti.org/#get-started
官方提供的一个工具
Activiti Modeler
这个工具是 war包 测试的话 自行去搭建 tomcat

地址 localhost:8080/activiti-explorer
默认用户名 密码
kermit kermit

在这个系统里 生成流程后 然后 导出 xml和 流程图片

然后把这两个资源 导入到resources 里
导入也可以用压缩包方式导入
这些操作 就不写了

然后测试

1. 流程定义部署

    @Test
    public void deployProcess(){
    
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("process/qingjia.bpmn20.xml")
                .addClasspathResource("process/qingjia.png")
                .name("请假流程")
                .deploy();
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());
    }

2. 启动一个流程实例

  //启动实例
    @Test
    public void startProcess(){
    
        ProcessInstance qingjia = runtimeService.startProcessInstanceByKey("qingjia");
        System.out.println("流程定义ID"+qingjia.getProcessDefinitionId());
        System.out.println("流程实例ID"+qingjia.getId());
        System.out.println("流程活动ID"+qingjia.getActivityId());
    }

3. 用户查询代办任务

    //查询个人代办任务 -- zhangsan
    @Test
    public void findTaskList(){
    
        String name="zhangsan";
        List<Task> taskList = taskService.createTaskQuery()
                .taskAssignee(name)
                .list();
        taskList.forEach(item->{
    
            System.out.println("流程实例的ID"+item.getProcessInstanceId());
            System.out.println("任务id"+item.getId());
            System.out.println("任务负责人"+item.getAssignee());
            System.out.println("任务名称"+item.getName());
        });

    }

4. 用户办理任务 (处理任务)

    @Test
    public void completTask(){
    
        String name="zhangsan";
        //查询负责人需要处理的任务 返回一条
        Task task = taskService.createTaskQuery().taskAssignee(name).singleResult();
        //处理任务 参数就是id
        taskService.complete(task.getId());
        //完成后会自动到下一个节点

    }

5. 查询已经处理的任务

   @Test
    public void findcompleteTaskList(){
    
        String name="zhangsan";
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(name)
                .finished().list();
        list.forEach(item->{
    
            System.out.println("流程实例的ID"+item.getProcessInstanceId());
            System.out.println("任务id"+item.getId());
            System.out.println("任务负责人"+item.getAssignee());
            System.out.println("任务名称"+item.getName());
        });

    }

====================================

什么叫流程实例
流程定义 ProcessDefinition和流程实例ProcessInstance是 activiti重要概念
类似于java类和java实例的关系
启动一个流程实例就是启动一个业务流程的运行
一个业务流程就要启动一个实例

让实际业务和activiti表关联(BusinessKey)
比如我们填写了一个请假单 一定会有一个请假单的唯一标识
通常会使用这个标识来关联activiti 这个标识在activiti中成为BusinessKey

BusinessKey:业务标识,通常为业务主键,业务标识和流程标识一一对应
业务标识来源于业务系统,存储业务标识就是根据业务标识来关联查询业务系统数据

举例 请假启动一个流程实例,将请假单的id作为业务标识存储到activiti中
将来查询activiti的流程实例信息就可以获取请假单的id从而关联查询业务系统里的请节单数据

测试:

 //启动实例 添加BusinessKey
    @Test
    public void startProcessBusinessKey(){
    
    //startProcessInstanceByKey 参数二
        ProcessInstance qingjia = runtimeService.startProcessInstanceByKey("qingjia","1001");
        System.out.println("流程定义ID"+qingjia.getProcessDefinitionId());
        System.out.println("流程实例ID"+qingjia.getId());
        System.out.println("流程活动ID"+qingjia.getActivityId());
        System.out.println("BusinessKey-业务id"+qingjia.getBusinessKey());
    }

==================================================================

挂起,激活流程实例

应用场景
比如 公司每个月的最后一天 需要封账,这个时候申请的报销审批 就可以挂起

  1. 全部流程实例挂起
    @Test
    public void suspendProcessInstance(){
    
           //1.获取流程定义对象
        ProcessDefinition qingjia = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("qingjia")
                .singleResult();
        //2. 调用流程定义对象的方法判断当前状态:挂起 还是激活
        boolean suspended = qingjia.isSuspended();
        //3. 判断挂起还是激活
        //如果 true 挂起状态 就要让他激活
        if(suspended){
    
            //那就执行激活
            //第一个参数 流程定义的id
            // 第二个参数 是否激活 true
            // 第三个参数 时间点
            repositoryService.activateProcessDefinitionById(qingjia.getId(),true,null);
            System.out.println("激活了");
        }else{
    
            repositoryService.suspendProcessDefinitionById(qingjia.getId(),true,null);
            System.out.println("挂起了");
        }
    }
  1. 单个的流程实例挂起
   @Test
    public void suspendProcessInstanceOne(){
    
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId("流程实例ID")
                .singleResult();
        boolean suspended = processInstance.isSuspended();
        //如果 true 挂起状态 就要让他激活
        if(suspended){
    
            //那就执行激活
            //第一个参数 流程定义的id
            // 第二个参数 是否激活 true
            // 第三个参数 时间点
            runtimeService.activateProcessInstanceById("流程实例ID");
            System.out.println("激活了");
        }else{
    
            runtimeService.startProcessInstanceByKey("流程实例ID");
            System.out.println("挂起了");
        }

    }
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Drug_/article/details/131886437

智能推荐

帧中继基本配置方法_帧中继 pvc inactive 怎么解决-程序员宅基地

文章浏览阅读7.4k次,点赞2次,收藏28次。帧中继基本配置1、 实验目的通过本实验可以掌握:A. 帧中继的基本配置;B. 帧中继的动态映射;C. 帧中继的静态映射;D. 帧中继上RIP的配置;E. 接口水平分割的开启与关闭2、 实验拓扑3、 实验步骤R1:_帧中继 pvc inactive 怎么解决

个人笔记--图的构造及DFS和BFS遍历_图的构造代码-程序员宅基地

文章浏览阅读347次。图的构造和两种遍历(DFS和BFS)图的构造函数Status LocateVex(MGraph G,VertexType u)//访问无向网图中该顶点所在位置{ int i; for(i=1;i<=G.vexnum;++i) if(G.vexs[i]==u) return i; return 0;}void CreateUDN(MGraph &G)//创建无向网图{ int i,j,k,w; VertexType v1,v2; char tmp; cout&_图的构造代码

学习vue源码(19)四探生命周期之初始化props,完整版开放下载-程序员宅基地

文章浏览阅读956次,点赞23次,收藏15次。javascript是前端必要掌握的真正算得上是编程语言的语言,学会灵活运用javascript,将对以后学习工作有非常大的帮助。掌握它最重要的首先是学习好基础知识,而后通过不断的实战来提升我们的编程技巧和逻辑思维。这一块学习是持续的,直到我们真正掌握它并且能够灵活运用它。如果最开始学习一两遍之后,发现暂时没有提升的空间,我们可以暂时放一放。继续下面的学习,javascript贯穿我们前端工作中,在之后的学习实现里也会遇到和锻炼到。真正学习起来并不难理解,关键是灵活运用。

十三、springboot 优雅集成spring-boot-admin 实现程序监控_spring-boot-admin+springboot2.6.13-程序员宅基地

文章浏览阅读478次,点赞23次,收藏6次。表示这个用户才能访问。在我们的启动类上加入@EnableAdminServer 注解,如果不加的话,项目可以正常启动,但是看不到任何东西。这样配置好之后,就可以启动项目啦,但是我们这里先不启动,因为上一节我们学习了,spring-boot-security .这里我们将它用起来。,面试的时候我们对知识的掌握有时候很难面面俱到,把自己的思路说出来,而不是直接告诉面试官自己不懂,这也是可以加分的。上面是我整个的pom 文件,可以看到我引入了web 、admin-starter-server、security。_spring-boot-admin+springboot2.6.13

润乾报表设计器连接数据源几个报错问题总结_润乾 error report listener-程序员宅基地

文章浏览阅读6.3k次。1.oracle数据库连接问题:本地数据库连接不上(启动监听),报错信息如下:这个产生这个问题的原因是listener服务不正常,因此需要重建这个服务。两个方式:先查一下本地的ip地址是否和监听中设置一样。不一样需要重新设置一下设置方法:第一个:打开oracle的net manager,设置这个主机的ip和在cmd里面查到的一样,保存刷新一下。重启监听即可。第二_润乾 error report listener

MAPLAB2.0论文阅读-2023_maplab2.0能使用雷达-程序员宅基地

文章浏览阅读313次。现在SLAM的热门研究-集成深度学习-多模态融合。大场景多机器人多段建图;非视觉地标的集成;将基于语义目标的回环检测模块合并到建图框架中。_maplab2.0能使用雷达

随便推点

Java学习步骤及路线(超详细)_java全面学习路线以及教程-程序员宅基地

文章浏览阅读2.2w次,点赞58次,收藏605次。我学习Java 已经快三年了,在 Java 学习这条路上也踩过无数次的坑,恰巧有小伙伴问我 Java 学习的路线,我想着趁这次机会分享自己学 Java 的路线,希望给小伙伴们一点帮助,避开路上的一些坑,一起进大厂。首先,我先分享下自己对不同学习方式的理解,小伙伴们可以根据自己情况选择。看视频系统学习,比如培训机构的课程、MOOC的课程等。看视频的好处就是有老师带着,易于理解和掌握,非常适合初学者。 看书学习,如《Redis设计与实现》、《 Java 并发编程的艺术》,便于了解技术脉络和深入学习_java全面学习路线以及教程

Python菜鸟之路:Python操作MySQL-即pymysql/SQLAlchemy用法-程序员宅基地

文章浏览阅读345次。上节介绍了Python对于RabbitMQ的一些操作,本节介绍Python对于MySQL的一些操作用法模块1:pymysql(等同于MySQLdb)  说明:pymysql与MySQLdb模块的使用基本相同,学会pymysql,使用MySQLdb也就不是问题安装API模块pip install pymysql执行          -->数据库test中表t1..._sqlalchemy 菜鸟教程

spi总线挂载多个设备的设备树描述_t113 spi 接多个设备-程序员宅基地

文章浏览阅读9.7k次,点赞3次,收藏9次。内核版本:linux4.6Vivado版本:201602工程中用到很多spi控制的从设备,首先对FPGA工程的正确性验证一下。验证的设备树描述如下:spi@e0006000 { compatible = "xlnx,zynq-spi-r1p6"; reg = &lt;0xe0006000 0x1000&gt;; ..._t113 spi 接多个设备

MyBatis基础知识复习_mybatis选择题-程序员宅基地

文章浏览阅读8.2k次,点赞13次,收藏47次。目 录作业3一.单选题二.填空题三.判断题作业3一.单选题1、MyBatis的删除操作有关说发错误的是()。A、MyBatis的删除操作在映射文件中是通过配置< delete >元素来实现的B、MyBatis的删除操作也需要进行事务提交C、MyBatis的删除操作执行了SqlSession的delete()方法D、MyBatis的删除操作和添加操作时,也需要封装整个实体类正确答案: D2、关于MyBatis模糊查询中进行SQL字符串拼接时,说法错误的是()。A、使用“${}”_mybatis选择题

安装国产银河麒麟系统(KylinOS)_国产麒麟系统重新安装-程序员宅基地

文章浏览阅读356次,点赞9次,收藏5次。此链接是我安装的版本镜像链接:https://pan.baidu.com/s/1lWuWWrYHocU8MFpFtVCwRQ?到此处就添加完毕啦,下面进行开启虚拟机安装。蓝色框框内选项自定义修改。蓝色框框内选项自定义修改。这里可敲回车进行下一步。_国产麒麟系统重新安装

TCP与UDP~第二式_tcp urgent pointer-程序员宅基地

文章浏览阅读4.7k次。# TCP与UDP一,分析TCP与UDP报文TCP与UDP都是位于OSI模型传输层的两个协议(1)UDP的报文头:如上图:UDP基本组成包括16位的源端口号和目的端口号+数据通过源端口号和目的端口号来进行传输;数据部分为保存的具体内容UDP的特点: 1,沟通简单,不需要处理逻辑、和数据结构; 2,不会建立连接,但是会监听这个地方,谁的数据都接收,也会传输数据给别人; 3,二愣子,传输完数据..._tcp urgent pointer

推荐文章

热门文章

相关标签