工作流引擎Flowable

这里写目录标题

  • 1.Flowable基础
    • 1.1 入门学习
  • 2.流程图设计器
    • 2.1 FlowableUI
    • 2.1.1 绘制流程图

1.Flowable基础

官方手册

1.1 入门学习

一、依赖

<dependencies>
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-engine</artifactId>
        <version>6.3.0</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
    </dependency>
    
	<dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.21</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.21</version>
    </dependency>

</dependencies>

二、demo

@Test
public void testProcessEngine() {
    // 获取config对象
    ProcessEngineConfiguration config = new StandaloneProcessEngineConfiguration();
    // 设置数据库连接
    config.setJdbcDriver("com.mysql.cj.jdbc.Driver");
    config.setJdbcUsername("root");
    config.setJdbcPassword("root");
    // 注意:要添加nullCatalogMeansCurrent=true属性, 不然会执行报错
    config.setJdbcUrl("jdbc:mysql://localhost:3306/flowable?serverTimezone=UTC&nullCatalogMeansCurrent=true");
    // 如果数据库中的表结构不存在, 就新建
    config.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
    // 构建我们需要的对象
    ProcessEngine processEngine = config.buildProcessEngine();
}

三、日志文件
在resources中添加日志文件log4j.properties

log4j.rootLogger=DEBUG, CA

log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n

2.流程图设计器

Flowable流程图

  • Eclipse Designer, 一款Eclipse插件, 用于图形化建模, 测试与部署BPMN2.0流程
  • FlowableUI
  • Flowable BPMN visualizer, 一款idea插件

2.1 FlowableUI

从官网下载flowable-6.7.2.zip解压后, 可以看到如下两个文件
在这里插入图片描述
将这两个文件, 扔到tomcat中, 并启动tomcat
在这里插入图片描述
之后我们就可以在网页中访问FlowableUI
访问地址
账户密码:admin/test
在这里插入图片描述

2.1.1 绘制流程图

一、创建流程
创建一个简单的请假流程
开始 > 提交审核流程(user1) > 总经理审批流程(user2) > 结束
在这里插入图片描述
二、部署
绘制好的流程图, 我们只需要一键导出即可(BPMN文件)
在这里插入图片描述
下载后, 将文件复制到idea中
在这里插入图片描述

private ProcessEngineConfiguration config;

    @Before
    public void before() {
        // 获取config对象
        config = new StandaloneProcessEngineConfiguration();
        // 设置数据库连接
        config.setJdbcDriver("com.mysql.cj.jdbc.Driver");
        config.setJdbcUsername("root");
        config.setJdbcPassword("root");
        // 注意:要添加nullCatalogMeansCurrent=true属性, 不然会执行报错
        config.setJdbcUrl("jdbc:mysql://localhost:3306/flowable?serverTimezone=UTC&nullCatalogMeansCurrent=true");
        // 如果数据库中的表结构不存在, 就新建
        config.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
    }

    /**
     * 部署流程
     */
    @Test
    public void testDeploy() {
        // 1.获取ProcessEngine对象
        ProcessEngine processEngine = config.buildProcessEngine();
        // 2.获取repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 3.完成流程的部署操作
        repositoryService.createDeployment()
                .addClasspathResource("MyHolidayUI.bpmn20.xml")
                .name("请求流程")
                .deploy();
    }
}

执行部署后, 我们回头看看表中的数据
act_re_procdef
act_re_deployment

三、执行流程

@Test
public void testRun() {
    // 1.获取ProcessEngine对象
    ProcessEngine processEngine = config.buildProcessEngine();
    // 2.获取runtimeService
    RuntimeService runtimeService = processEngine.getRuntimeService();
    // 3.启动流程实例
    ProcessInstance processInstance = runtimeService.startProcessInstanceById("MyHolidayUI:1:4");
    System.out.println("processDefinitionId = " + processInstance.getProcessDefinitionId());
    System.out.println("activityId = " + processInstance.getActivityId());
    System.out.println("id = " + processInstance.getId());
}

在这里插入图片描述
可以通过act_ru_task查看任务流程
在这里插入图片描述
在这里插入图片描述

四、用户处理
user1对任务进行处理

@Test
public void testCompleteTask() {
    // 1.获取ProcessEngine对象
    ProcessEngine processEngine = config.buildProcessEngine();
    // 2.获取TaskService
    TaskService taskService = processEngine.getTaskService();
    // 3.获取任务
    Task task = taskService.createTaskQuery()
            .processDefinitionKey("MyHolidayUI")
            .taskAssignee("user1")
            .singleResult();
    // 4.创建流程变量
    HashMap<String, Object> map = new HashMap<>();
    map.put("approved", false);
    // 5.完成任务
    taskService.complete(task.getId(), map);
}

处理完成后, 任务就流转到user2了
在这里插入图片描述
user2对任务进行处理

@Test
public void testCompleteTask() {
    // 1.获取ProcessEngine对象
    ProcessEngine processEngine = config.buildProcessEngine();
    // 2.获取TaskService
    TaskService taskService = processEngine.getTaskService();
    // 3.获取任务
    Task task = taskService.createTaskQuery()
            .processDefinitionKey("MyHolidayUI")
            .taskAssignee("user2")
            .singleResult();
    // 4.创建流程变量
    HashMap<String, Object> map = new HashMap<>();
    map.put("approved", false);
    // 5.完成任务
    taskService.complete(task.getId(), map);
}

user2处理完成后, 任务就结束了, 在task表中就删除了这条记录
在这里插入图片描述
五、查看历史信息

@Test
public void testHistory() {
    // 1.获取ProcessEngine对象
    ProcessEngine processEngine = config.buildProcessEngine();
    // 2.获取historyService
    HistoryService historyService = processEngine.getHistoryService();
    // 3.获取任务
    List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
            .processDefinitionId("MyHolidayUI:1:4")
            .finished() // 查询已完成的历史记录
            .orderByHistoricActivityInstanceEndTime().asc() // 指定排序的字段
            .list();

    for (HistoricActivityInstance history : list) {
        System.out.println(history.getActivityName() + ":" + history.getAssignee() + "--"
                + history.getActivityId() + ":" + history.getDurationInMillis() + "毫秒");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/30606.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android系统安全 — 6.2 Ethernet安卓架构

1. Android Ethernet架构介绍 整个Ethernet系统架构如下图所示&#xff1a; 以太网服务&#xff08;EthernetService&#xff09;的启动与注册流程&#xff1b;应用层调用使能ethernet功能的方法流程来分析&#xff0c;从应用层如何将指令一步一步传到底层kernel&#xff1b;…

阿里巴巴开源的Spring Cloud Alibaba手册在GitHub上火了

“微服务架构经验你有吗&#xff1f;” 前段时间一个朋友去面试&#xff0c;阿里面试官一句话问倒了他。实际上&#xff0c;不在BAT这样的大厂工作&#xff0c;是很难接触到支撑千亿级流量微服务架构项目的。但也正是这种难得&#xff0c;让各个大厂都抢着要这样的人才&#x…

docker-harbor私有仓库

一、Harbor概述 1、Harbor的概念 • Harbor是VMware公司开源的企业级Docker Registry项目&#xff0c;其目标是帮助用户迅速搭建一个企业级的Docker Registry服务 • Harbor以 Docker 公司开源的Registry 为基础&#xff0c;提供了图形管理UI、基于角色的访问控制(Role Base…

华为流程体系:IPD流程框架(限制版)

目录 前言 详细内容 专栏列表 CSDN学院课程地址 前言 今天主要来谈谈 IPD 体系的主体框架所涉及的一些相关内容。 其实关于 IPD 体系&#xff0c;我在之前的文章或课程中都有过不同程度的讲解。 但是&#xff0c;由于这个体系所涉及的面是非常广泛的。 这个时候就必须通…

sql总理论加实践

一、基础查询 DQL语法 SELECT 字段列表 1.设置别名 SELECT 字段1[别名],字段二[别名]......FROM 表名 WHERE 条件列表; 2.查询多个字段 SELECT 字段1,字段2,字段3......FROM 表名; SELECT * FROM 表名; 3.去除重复记录 DISTANT FROM 表明列表 WHERE 条件列表(条件…

利用etcd实现分布式锁

python etcd3模块的lock使用 观察lock的加解锁影响 在python中已经自带了分布式锁的实现方式&#xff0c;下面我们尝试一下加锁与解锁的流程 在运行该demo同时也对lock对应的key进行watch&#xff0c;观察其变化&#xff0c;注意python-etcd3在实现分布式锁的时候&#xff0…

【Python爬虫开发基础⑤】HTML概述与基本标签详解

专栏&#xff1a;python网络爬虫从基础到实战 欢迎订阅&#xff01;近期还会不断更新~ 往期推荐&#xff1a; 【Python爬虫开发基础①】Python基础&#xff08;变量及其命名规范&#xff09; 【Python爬虫开发基础②】Python基础&#xff08;正则表达式&#xff09; 【Python爬…

探秘华为交换机:端口类型全解析

在下列情况下&#xff0c;判断的一般方法是什么&#xff1f; 1.交换机某个端口下的用户丢包。 2.交换机下的所有用户都在丢失数据包。 3、用户反映网速缓慢 检查网络电缆&#xff0c;重做水晶头&#xff0c;检查用户的计算机网卡&#xff0c;并重新启动交换机。 这几种做法都能…

Flink 学习五 Flink 时间语义

Flink 学习五 Flink 时间语义 1.时间语义 在流式计算中.时间是一个影响计算结果非常重要的因素! (窗口函数,定时器等) Flink 可以根据不同的时间概念处理数据。 处理时间: process time System.currentTimeMillis()是指执行相应操作的机器系统时间&#xff08;也称为纪元时间…

Docker安全

一、Docker 容器与虚拟机的区别 1、隔离与共享 • 虚拟机通过添加 Hypervisor 层&#xff0c;虚拟出网卡、内存、CPU 等虚拟硬件&#xff0c;再在其上建立虚拟机&#xff0c;每个虚拟机都有自己的系统内核 • Docker容器则是通过隔离的方式&#xff0c;将文件系统、进程、设…

Redis入门 - Lua脚本

原文首更地址&#xff0c;阅读效果更佳&#xff01; Redis入门 - Lua脚本 | CoderMast编程桅杆https://www.codermast.com/database/redis/redis-scription.html Redis 脚本使用 Lua 解释器来执行脚本。 Redis 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL。 …

Spark01-Spark快速上手、运行模式、运行框架、核心概念

1 概述 Spark和Hadoop Hadoop HDFS(GFS:TheGoogleFileSystem)MapReduce总结&#xff1a;性能横向扩展变得容易&#xff0c;横向拓展:增加更多的计算节点来扩展系统的处理能力Hbase&#xff1a;分布式数据库 Spark Spark CoreSpark SQLSQL 方言&#xff08;HQL)Spark Streamin…

光伏电池局部遮阴下三种不同的工况对比MATLAB仿真模型

光伏电池局部遮阴下三种不同的工况对比MATLAB仿真模型及程序资源-CSDN文库https://download.csdn.net/download/weixin_56691527/87910311 模型简介&#xff1a; 建议使用MATLAB21b及以上版本打开&#xff01; 光伏阵列表面被局部遮挡时会产生热斑效应。为了防止太阳电池因热…

【Matter】Matter学习笔记1

文章目录 前言Matter协议架构1.Matter Over IPV62.Matter协议架构3.Matter标准协议架构 Matter网络拓扑结构Mesh组网1.单一网络拓扑2.星形网络拓扑 设备数据模型&#xff08;Date Model&#xff09;1.设备和端点&#xff08;Node、Endpoint&#xff09;2.节点角色&#xff08;N…

ADAudit Plus:保护企业内部IT安全的强大解决方案

随着企业数字化的推进&#xff0c;IT系统和数据安全变得比以往任何时候都更加重要。为了保护企业的机密信息和敏感数据&#xff0c;企业需要一种可靠的IT安全解决方案。在众多选项中&#xff0c;ADAudit Plus是一款备受赞誉的软件&#xff0c;为企业内部的IT安全提供了强大的支…

工业机器人运动学与Matlab正逆解算法学习笔记(用心总结一文全会)(二)

文章目录 机器人逆运动学※ 代数解、几何解&#xff0c;解析解&#xff08;封闭解&#xff09;、数值解的含义与联系○ 代数解求 θ 1 \theta_1 θ1​、 θ 2 \theta_2 θ2​、 θ 3 \theta_3 θ3​※参考资料 求解 θ 1 \theta_1 θ1​ 求解 θ 3 \theta_3 θ3​ 求解 θ 2 \t…

Unity核心7——2D动画

一、序列帧动画 &#xff08;一&#xff09;什么是序列帧动画 ​ 我们最常见的序列帧动画就是我们看的日本动画片&#xff0c;以固定时间间隔按序列切换图片&#xff0c;就是序列帧动画的本质 ​ 当固定时间间隔足够短时&#xff0c;我们肉眼就会认为图片是连续动态的&#…

【Java基础学习打卡11】Path环境变量的配置

目录 前言一、为什么配置环境变量二、如何配置环境变量三、JDK11的环境变量配置总结 前言 本文我们要知道为什么配置环境变量&#xff0c;自己思考不配置环境变量可以吗&#xff1f;JDK 11 如何配置环境变量。 一、为什么配置环境变量 原因很简单&#xff0c;就是方便命令的查…

1.5 掌握Scala内建控制结构(一)

一、条件表达式 &#xff08;一&#xff09;语法格式 if (条件) 值1 else 值2 &#xff08;二&#xff09;执行情况 条件为真&#xff0c;结果是值1&#xff1b;条件为假&#xff0c;结果是值2。如果if和else的返回结果同为某种类型&#xff0c;那么条件表达式结果也是那种…

【STM32MP135 - ST官方源码移植】第二章:TF-A源码移植教程

STM32MP135 TF-A源码移植教程 一、创建build.sh编译脚本&#xff08;1&#xff09;解压tf-a的源码压缩包&#xff08;2&#xff09;打补丁&#xff0c;获取stm32mp135的源码&#xff08;3&#xff09;设计编译脚本build.sh1、进入tf-a源码&#xff1a;2、创建build.sh脚本文件3…