热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

FlowableBPMN用户手册

一、Flowable介绍Flowable是BPMN的一个基于java的软件实现,不过Flowable不仅仅包含BPMN,还有BMN决策表和CMMNCas

一、Flowable介绍 

        Flowable是BPMN的一个基于java的软件实现,不过Flowable不仅仅包含BPMN,还有BMN决策表和CMMN Case管理引擎,并且有自己的用户管理、微服务API等一系列功能,是一个微服务平台。


二、Flowbale基础

官方:Flowable BPMN 用户手册 (v 6.3.0)


1、创建流程引擎

引入依赖

org.flowableflowable-engine6.3.0mysqlmysql-connector-java8.0.21junitjunit4.13.2test

获取流程引擎对象

public class Test01 {/*** 获取流程引擎对象*/@Testpublic void testProcessEngine() {// 获取 ProcessEngineConfiguration 对象ProcessEngineConfiguration configuration = new StandaloneProcessEngineConfiguration();// 配置 相关的数据库连接信息configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");configuration.setJdbcUsername("root");configuration.setJdbcPassword("zq@123456");// UTC是统一标准世界时间configuration.setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn?serverTimezone=UTC");// 如果数据库中的表结构不存在就新建configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 通过 ProcessEngineConfiguration 构建 processEngine 对象ProcessEngine processEngine = configuration.buildProcessEngine();}
}

控制台提示日志没有正确配置:

Flowable使用SLF4J作为内部日志框架。因此在pom.xml文件中添加下列依赖:

org.slf4jslf4j-api1.7.21org.slf4jslf4j-log4j121.7.21

Log4j需要一个配置文件。

src/main/resources文件夹下添加log4j.properties文件,并写入下列内容:

log4j.rootLogger=DEBUG, CAlog4j.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

重新运行应用,可以看到关于引擎启动与创建数据库表结构的提示日志:

flowable-engine6.3.0生成的表: 

flowable-engine6.7.2生成的表: 

数据库表名说明:

Flowable的所有数据库表都以ACT_开头。第二部分是说明表用途的两字符标示符。服务API的命名也大略符合这个规则。


  • ACT_RE_*: 'RE’代表repository。带有这个前缀的表包含“静态”信息,例如流程定义与流程资源(图片、规则等)。

  • ACT_RU_*: 'RU’代表runtime。这些表存储运行时信息,例如流程实例(process instance)、用户任务(user task)、变量(variable)、作业(job)等。Flowable只在流程实例运行中保存运行时数据,并在流程实例结束时删除记录。这样保证运行时表小和快。

  • ACT_HI_*: 'HI’代表history。这些表存储历史数据,例如已完成的流程实例、变量、任务等。

  • ACT_GE_*: 通用数据。在多处使用。


2、部署流程

我们要构建的流程是一个非常简单的请假流程。

Flowable引擎需要流程定义为BPMN 2.0格式,这是一个业界广泛接受的XML标准。 在Flowable术语中,我们将其称为一个流程定义(process definition)。一个流程定义可以启动多个流程实例(process instance)流程定义可以看做是重复执行流程的蓝图。

在这个例子中,流程定义定义了请假的各个步骤,而一个流程实例对应某个雇员提出的一个请假申请。

BPMN 2.0存储为XML,并包含可视化的部分:使用标准方式定义了每个步骤类型(人工任务,自动服务调用,等等)如何呈现,以及如何互相连接。这样BPMN 2.0标准使技术人员与业务人员能用双方都能理解的方式交流业务流程。

我们要使用的流程定义为:

将下面的XML保存在src/main/resources文件夹下名为holiday-request.bpmn20.xml的文件中。




2.1 部署流程具体实现

ProcessEngineConfiguration configuration = null;@Before// import org.junit.Before; 在一个类中最先执行的方法public void before(){// 获取 ProcessEngineConfiguration 对象configuration = new StandaloneProcessEngineConfiguration();// 配置 相关的数据库连接信息configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");configuration.setJdbcUsername("root");configuration.setJdbcPassword("zq@123456");// UTC是统一标准世界时间configuration.setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn?serverTimezone=UTC");// 如果数据库中的表结构不存在就新建configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);}/*** 部署流程*/@Testpublic void testDeploy(){// 1、获取 ProcessEngine 对象ProcessEngine processEngine = configuration.buildProcessEngine();// 2、获取RepositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();// 3、完成流程的部署操作Deployment deploy = repositoryService.createDeployment().addClasspathResource("holiday-request.bpmn20.xml") // 关联要部署的流程文件.name("请假流程").deploy(); // 部署流程System.out.println("deploy.getId() = " + deploy.getId());System.out.println("deploy.getName() = " + deploy.getName());}

act_ge_bytearray、act_re_deployment、act_re_procdef表可查看到相关信息。


2.2 查询操作

/*** 查询流程定义的信息*/@Testpublic void testDeployQuery() {ProcessEngine processEngine = configuration.buildProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();// 查询单个ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId("1").singleResult();System.out.println("processDefinition.getName() = " + processDefinition.getName());System.out.println("processDefinition.getId() = " + processDefinition.getId());System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());}


2.3 删除操作

/*** 删除流程定义*/@Testpublic void testDeleteDeploy() {ProcessEngine processEngine = configuration.buildProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();// 删除部署的流程 第一个参数id,如果部署的流程启动了就不允许删除
// repositoryService.deleteDeployment("1");// 第二个参数是级联删除,如果部署的流程启动了 相关的任务会一并被删除repositoryService.deleteDeployment("1", true);}

删除后:act_ge_bytearray、act_re_deployment、act_re_procdef表相关信息都被删除


3、启动流程实例

/*** 启动流程实例*/@Testpublic void testRunProcess() {ProcessEngine processEngine = configuration.buildProcessEngine();// 通过RuntimeService启动流程实例RuntimeService runtimeService = processEngine.getRuntimeService();// 构建流程变量Map variables = new HashMap();variables.put("employee", "zhangsan");variables.put("nrOfHolidays", 3);variables.put("description", "累了,休息休息");// 流程key ProcessInstance holidayRequest = runtimeService.startProcessInstanceByKey("holidayRequest", variables);System.out.println("holidayRequest.getProcessDefinitionId() = " + holidayRequest.getProcessDefinitionId());System.out.println("holidayRequest.getActivityId() = " + holidayRequest.getActivityId());System.out.println("holidayRequest.getId() = " + holidayRequest.getId());System.out.println("holidayRequest.getName() = " + holidayRequest.getName());}

act_ru_variable、 act_ru_task、act_ru_execution表可查看到相关信息。


此流程的deploymentId为5001,此流程已启动,删除时需级联删除。
如:repositoryService.deleteDeployment("5001", true);



4、查询任务

在更实际的应用中,会为雇员及经理提供用户界面,让他们可以登录并查看任务列表。

其中可以看到作为流程变量存储的流程实例数据,并决定如何操作任务。


4.1 分配处理人

在这个例子中,我们还没有为用户任务配置办理人。我们想将第一个任务指派给"经理(managers)"组,而第二个用户任务指派给请假申请的提交人。

为第一个任务添加candidateGroups属性(’managers’使用的静态值):

为第二个任务添加assignee属性(使用一个流程变量动态指派,这个流程变量是在流程实例启动时传递的):


4.2 重新部署流程并启动流程实例

部署流程:

启动流程实例:


4.3 查询“managers”组的任务

/*** 测试任务查询*/@Testpublic void testQueryTask() {ProcessEngine processEngine = configuration.buildProcessEngine();TaskService taskService = processEngine.getTaskService();// 查询“managers”组的任务List tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();System.out.println("You have " + tasks.size() + " tasks:");for (Task task : tasks) {System.out.println("task.getId() = " + task.getId());System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());System.out.println("task.getDescription() = " + task.getDescription());System.out.println("task.getTaskDefinitionId() = " + task.getTaskDefinitionId());System.out.println("task.getTaskLocalVariables() = " + task.getTaskLocalVariables());}}


5、处理任务

在BPMN 2.0 XML中,这是一个服务任务(service task):

创建一个相关类填入org.flowable作为包名,CallExternalSystemDelegate作为类名。让这个类实现org.flowable.engine.delegate.JavaDelegate接口,并实现execute方法:

package org.flowable;import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;public class CallExternalSystemDelegate implements JavaDelegate {@Overridepublic void execute(DelegateExecution execution) {// 触发执行的逻辑 请假申请通过System.out.println("请假申请通过");System.out.println("Calling the external system for employee "+ execution.getVariable("employee"));}
}

创建一个相关类填入org.flowable作为包名,SendRejectionMail 作为类名。让这个类实现org.flowable.engine.delegate.JavaDelegate接口,并实现execute方法:

package org.flowable;import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;public class SendRejectionMail implements JavaDelegate {@Overridepublic void execute(DelegateExecution execution) {// 触发执行的逻辑 被拒绝的员工发送通知的邮件System.out.println("不好意思,你的请假申请被拒绝......安心工作");}
}

任务完成,并会在离开排他网关的两条路径中,基于’approved’流程变量选择一条。


5.1 请假申请通过

/*** 完成当前任务*/&#64;Testpublic void testCompleteTask() {ProcessEngine processEngine &#61; configuration.buildProcessEngine();TaskService taskService &#61; processEngine.getTaskService();Task task &#61; taskService.createTaskQuery().processDefinitionId("holidayRequest:1:10003").taskCandidateGroup("managers").singleResult();// 创建流程bianlMap map &#61; new HashMap<>();map.put("approved", true);// 完成taskService.complete(task.getId(), map);}

 当执行到达服务任务时&#xff0c;会初始化并调用BPMN 2.0 XML中所引用的类。

现在执行这个例子的时候&#xff0c;就会显示出日志信息&#xff0c;说明已经执行了自定义逻辑&#xff1a;


5.2 请假申请不通过

/*** 完成当前任务*/&#64;Testpublic void testCompleteTask() {ProcessEngine processEngine &#61; configuration.buildProcessEngine();TaskService taskService &#61; processEngine.getTaskService();Task task &#61; taskService.createTaskQuery().processDefinitionId("holidayRequest:3:20003").taskCandidateGroup("managers").singleResult();// 创建流程bianlMap map &#61; new HashMap<>();map.put("approved", false);// 完成taskService.complete(task.getId(), map);}

日志信息&#xff1a;


6、历史任务查询

选择使用Flowable这样的流程引擎的原因之一&#xff0c;是它可以自动存储所有流程实例的审计数据历史数据。这些数据可以用于创建报告&#xff0c;深入展现组织运行的情况&#xff0c;瓶颈在哪里&#xff0c;等等。

例如&#xff0c;如果希望显示流程实例已经执行的时间&#xff0c;就可以从ProcessEngine获取HistoryService&#xff0c;并创建历史活动(historical activities)的查询。

/*** 获取流程任务的历史数据*/&#64;Testpublic void testHistory() {ProcessEngine processEngine &#61; configuration.buildProcessEngine();HistoryService historyService &#61; processEngine.getHistoryService();List list &#61; historyService.createHistoricActivityInstanceQuery().processDefinitionId("holidayRequest:3:20003").finished() // 查询历史记录的状态是已完成.orderByHistoricActivityInstanceEndTime().asc() // 指定排序的字段和顺序.list();for (HistoricActivityInstance historicActivityInstance : list) {System.out.println(historicActivityInstance.getId() &#43; ":" &#43; historicActivityInstance.getActivityName() &#43; ":" &#43; historicActivityInstance.getAssignee()&#43; ":" &#43; historicActivityInstance.getActivityId() &#43; ":" &#43; historicActivityInstance.getDurationInMillis() &#43; "毫秒");}}


三、Flowable UI应用


  1. 下载最新稳定版本的Apache Tomcat。

  2. 下载最新稳定版本的Flowable 6。

  3. 将Flowable发行包中&#xff0c;wars文件夹下的flowable-admin.war、flowable-idm.war、flowable-modeler.war与flowable-task.war文件&#xff0c;复制到Tomcat的webapps文件夹下。

  4. 运行bin/startup.sh&#xff08;在Mac OS或Linux下&#xff09;&#xff0c;或bin/startup.bat&#xff08;在Windows下&#xff09;脚本&#xff0c;启动Tomcat服务器。

  5. 打开web浏览器&#xff0c;访问Flowable IDM&#xff0c;默认账号admin 密码test

 

 


推荐阅读
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了[从头学数学]中第101节关于比例的相关问题的研究和修炼过程。主要内容包括[机器小伟]和[工程师阿伟]一起研究比例的相关问题,并给出了一个求比例的函数scale的实现。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
author-avatar
天之道
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有