• Flowable工作流


    一、Flowable介绍

    官方地址:https://www.flowable.com/open-source/docs/oss-introduction

    中文V6.3.0文档地址 Flowable BPMN 用户手册 (v 6.3.0) (tkjohn.github.io)

    flowable是BPMN2.0 的一个基于java的工作流引擎实现,flowable不仅包括了BPMN,还有DMN决策表和CMMN Case管理引擎,并且有自己的用户管理,微服务API等一系列功能,是一个服务平台。

    flowableActiviti有一些渊源,flowable的主程是Activiti的作者,从Activiti6开始,主程自己带人做了flowable。所以flowable是由Activiti6演变过来的

    二、Flowable基础知识

    1.创建ProcessEngine

    创建一个基本的maven工程,添加flowable依赖和mysql依赖以及junit

        <dependency>
          <groupId>org.flowablegroupId>
          <artifactId>flowable-engineartifactId>
          <version>6.5.0version>
        dependency>
        <dependency>
          <groupId>mysqlgroupId>
          <artifactId>mysql-connector-javaartifactId>
          <version>8.0.21version>
        dependency>
        <dependency>
          <groupId>junitgroupId>
          <artifactId>junitartifactId>
          <version>4.13.2version>
          <scope>testscope>
        dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    配置日志打印

    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
    
    • 1
    • 2
    • 3
    • 4
        @Test
        public void testProcessEngine(){
            // 创建 ProcessEngineConfiguration
            ProcessEngineConfiguration configuration = new StandaloneProcessEngineConfiguration();
            // 配置数据库连接指令
            configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
            configuration.setJdbcUsername("root");
            configuration.setJdbcPassword("x");
            configuration.setJdbcUrl("jdbc:mysql://192.168.1.xx:3306/flowable-learn?serverTimezone=UTC&nullCatalogMeansCurrent=true");
            // 配置表生成策略
            configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
            // 通过  ProcessEngineConfiguration 构建 processEngine
            ProcessEngine processEngine = configuration.buildProcessEngine();
    
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    运行成功后,数据库会生成表,其中比较重要的有

    act_ge_bytearry 定义了流程信息

    act_re_deployment 流程部署信息

    act_ru_job 工作

    act_ru_task 任务

    可以注意到,flowable中的表和Activiti相似度高

    2.部署流程定义

    Flowable引擎需要流程定义为BPMN2.0格式,这是一个业界接受的XML标准。

    一个BPMN可以称之为一个流程定义Process definition。一个流程定义又可以启动多个流程实例Process instance。

    下面是员工请假流程,流程定义 定义了请假的各个步骤,而流程实例对应员工提出的请假申请。

    对下面流程图有疑问的可以参考我的博客 Activiti基础知识

    在这里插入图片描述

    保存xml到工作空间/main/resources下面,命名holiday-request.bpmn20.xml

    
    <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: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"
      xmlns:flowable="http://flowable.org/bpmn"
      typeLanguage="http://www.w3.org/2001/XMLSchema"
      expressionLanguage="http://www.w3.org/1999/XPath"
      targetNamespace="http://www.flowable.org/processdef">
    
      <process id="holidayRequest" name="Holiday Request" isExecutable="true">
    
        <startEvent id="startEvent"/>
        <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>
    
        <userTask id="approveTask" name="Approve or reject request"/>
        <sequenceFlow sourceRef="approveTask" targetRef="decision"/>
    
        <exclusiveGateway id="decision"/>
        <sequenceFlow sourceRef="decision" targetRef="externalSystemCall">
          <conditionExpression xsi:type="tFormalExpression">
            
          conditionExpression>
        sequenceFlow>
        <sequenceFlow  sourceRef="decision" targetRef="sendRejectionMail">
          <conditionExpression xsi:type="tFormalExpression">
            
          conditionExpression>
        sequenceFlow>
    
        <serviceTask id="externalSystemCall" name="Enter holidays in external system"
            flowable:class="org.flowable.CallExternalSystemDelegate"/>
        <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/>
    
        <userTask id="holidayApprovedTask" name="Holiday approved"/>
        <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>
    
        <serviceTask id="sendRejectionMail" name="Send out rejection email"
            flowable:class="org.flowable.SendRejectionMail"/>
        <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/>
    
        <endEvent id="approveEnd"/>
    
        <endEvent id="rejectEnd"/>
    
      process>
    
    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
    • 52
    • 53
    • 54

    流程引擎下面比较重要的服

    ProcessEngine

    -RepositoryService

    -RuntimeService

    -TaskService

    -HistoryService

    添加部署测试

        /**
         * 获取流程引擎对象
         */
        @Before
        public void testProcessEngine(){
    
            // 配置数据库连接指令
            configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
            configuration.setJdbcUsername("root");
            configuration.setJdbcPassword("x
            ");
            configuration.setJdbcUrl("jdbc:mysql://192.168.1.x:3306/flowable-learn?serverTimezone=UTC&nullCatalogMeansCurrent=true");
            // 配置表生成策略
            configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
            // 通过  ProcessEngineConfiguration 构建 processEngine
            ProcessEngine processEngine = configuration.buildProcessEngine();
    
        }
        /***
         * 部署流程
         */
        @Test
        public void testDeploy(){
            // 获取 ProcessEngine
            ProcessEngine processEngine = configuration.buildProcessEngine();
            // 获取资源对象
            RepositoryService repositoryService = processEngine.getRepositoryService();
            // 完成流程的部署操作
            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());
        }
    
    • 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

    查看数据库

    在表ACT_GE_BYTEARRY中新增了一条bpmn信息
    在这里插入图片描述

    在ACT_RE_PROCDEF中新增了一条流程定义信息

    在这里插入图片描述

    在表ACT_RE_DEPLOYMENT中新增了一条部署记录

    在这里插入图片描述

    产看流程定义、删除流程定义

         * 查询流程定义信息
         */
        @Test
        public void testDeployQuery(){
            ProcessEngine processEngine = configuration.buildProcessEngine();
            RepositoryService repositoryService = processEngine.getRepositoryService();
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                    .deploymentId("1")
                    .singleResult();
            System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());
            System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());
            System.out.println("processDefinition.getName() = " + processDefinition.getName());
            System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());
    
        }
    
        /***
         * 删除流程定义信息
         */
        @Test
        public void testDeleteQuery(){
            ProcessEngine processEngine = configuration.buildProcessEngine();
            RepositoryService repositoryService = processEngine.getRepositoryService();
            // 删除部署流程,第一个参数是id,如果部署流程启动了,不允许删除
            repositoryService.deleteDeployment("1");
            // 第二个参数是级联参数,如果流程启动了,相关的任务会一并删除
            // repositoryService.deleteDeployment("1", true);
        }
    
    • 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

    3.启动流程实例

    现在已经在流程引擎中部署了流程定义,因此可以使用流程定义作为模板,来启动易流程实例

        /***
         * 启动流程实例
         */
        @Test
        public void testRunProcess(){
            ProcessEngine processEngine = configuration.buildProcessEngine();
            // 通过runtimeService启动流程实例
            RuntimeService runtimeService = processEngine.getRuntimeService();
            // 构建流程变量,其实在业务中是从表单传递过来的
            Map<String,Object> varivales = new HashMap<>();
            varivales.put("employee", "张三");
            varivales.put("nrOfHolidays",3);
            varivales.put("description","感冒了,想要休息");
            // 启动流程实例
            runtimeService.startProcessInstanceByKey("holidayRequest", varivales);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ACT_RU_VARIABLE表中记录了流程变量信息

    在这里插入图片描述

    ACT_RU_TASK中记录了任务信息

    在这里插入图片描述

    ACT_RU_EXECUTION中记录了流程信息

    4.查看任务

    上面员工发起了一个请假流程,接下来就会流转到总经理处理,案例中的BPMN没有指定经理这的处理人,我们可以加一个

    <userTask id="approveTask" name="Approve or reject request" flowable:assignee="lisi"/>
    
    • 1

    级联删除以前的流程,

    重新部署流程

    发起请假申请

    任务查询

        /***
         * 测试任务查询
         */
        @Test
        public void testQueryTask(){
            ProcessEngine processEngine = configuration.buildProcessEngine();
            TaskService taskService = processEngine.getTaskService();
            List<Task> list = taskService.createTaskQuery()
                    .processDefinitionKey("holidayRequest")// 指定查询的流程编号
                    .taskAssignee("lisi")// 查询这个任务的处理人
                    .list();
            for (Task task : list) {
                System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());
                System.out.println("task.getAssignee() = " + task.getAssignee());
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    5.完成任务

        /***
         * 完成任务
         */
        @Test
        public void testCompleteTask(){
            ProcessEngine processEngine = configuration.buildProcessEngine();
            TaskService taskService = processEngine.getTaskService();
            List<Task> list = taskService.createTaskQuery()
                    .processDefinitionKey("holidayRequest")// 指定查询的流程编号
                    .taskAssignee("lisi")// 查询这个任务的处理人
                    .list();
            // 构建流程变量
            Map<String,Object> varivales = new HashMap<>();
            varivales.put("approved", "false");
            for (Task task : list) {
                taskService.complete(task.getId(), varivales);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    重写org.flowable.SendRejectionMail 实现javaDeleagte委托类接口,实现自定义逻辑

    6.流程的删除

    
        /***
         * 删除流程定义信息
         */
        @Test
        public void testDeleteProcessDefine (){
            ProcessEngine processEngine = configuration.buildProcessEngine();
            RepositoryService repositoryService = processEngine.getRepositoryService();
            // 删除部署流程,第一个参数是id,如果部署流程启动了,不允许删除
            // repositoryService.deleteDeployment("1");
            // 第二个参数是级联参数,如果流程启动了,相关的任务会一并删除
            repositoryService.deleteDeployment("5001", true);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    7.查看历史信息

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

    例如,如果蜥蜴王显示流程实例已经执行的时间,就可以从ProcessEngine获取HistoryService,并创建历史活动(historical activies)的查询。在下面的代码片段中,我们可以看到我们添加了一些额外的过滤条件:

    1. 只选择一个特定流程实例的活动
    2. 只选择已完成的活动

    结果按照结束时间排序,代表执行顺序

    /***
     * 获取流程任务历史数据
     */
    @Test
    public void testHistory(){
        ProcessEngine processEngine = configuration.buildProcessEngine();
        HistoryService historyService = processEngine.getHistoryService();
        historyService.createHistoricActivityInstanceQuery()
                .processDefinitionId("holidayRequest:1:7503")
                .finished() // 查询历史记录的状态是完成的
                .orderByHistoricActivityInstanceEndTime().asc()// 指定排序的字段
                .list();
        for (;;){
            // 打印history消耗的时间、处理人、名称、任务编号等等
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    三、流程设计器

    1.Eclipse 插件

    https://eclipse.org/downloads/packages/release

    注意 2020-06及以后版本支持JDK8

    注意:

    安装插件的方式有坑

    本人比较懒,因为现在使用的是idea,电脑上的eclipse版本又比较老,所以想使用第二种方式。

    2.Flowable UI应用

    安装部署

    第一步

    安装说明地址

    https://tkjohn.github.io/flowable-userguide/#flowableUIApps

    tomcat下载地址

    https://tomcat.apache.org/

    flowable下载地址

    https://www.flowable.com/open-source

    第二步

    解压后的war包放到tomcat的webapps下面。tomcat下的/bin/start.bat启动(如果启动乱码,检查conf/properties编码UTF-8/GBK)

    第三步

    登录 localhost:8080/flowable-ui,

    账号密码 admin/test

    控制台窗口能看到四个模块,就是下面官网中提到的内容

    Flowable提供了几个web应用,用于演示及介绍Flowable项目提供的功能:

    • Flowable IDM: 身份管理应用。为所有Flowable UI应用提供单点登录认证功能,并且为拥有IDM管理员权限的用户提供了管理用户、组与权限的功能。
    • Flowable Modeler: 让具有建模权限的用户可以创建流程模型、表单、选择表与应用定义。
    • Flowable Task: 运行时任务应用。提供了启动流程实例、编辑任务表单、完成任务,以及查询流程实例与任务的功能。
    • Flowable Admin: 管理应用。让具有管理员权限的用户可以查询BPMN、DMN、Form及Content引擎,并提供了许多选项用于修改流程实例、任务、作业等。管理应用通过REST API连接至引擎,并与Flowable Task应用及Flowable REST应用一同部署。

    绘制流程

    点击创建新模型,创建一个新的流程

    流程图界面

    在这里插入图片描述

    创建流程,分配处理人

    在这里插入图片描述

    绘制好的流程

    在这里插入图片描述

    部署流程

    1.点击按钮导出 BPMN2
    在这里插入图片描述

    2.将导出的xml文件复制到 main/resources/下面

    3.按照test测试类中的顺序部署流程定义,创建流程实例、

    本篇文章工程github地址

    https://github.com/cuim/flowable-demo17

    其他实践参考地址

    https://blog.csdn.net/qq_44787816/article/details/125303284

  • 相关阅读:
    打家劫舍3(二叉树型)Java
    【动态顺序表实现-C++】
    如何进行日期和时间的计算和操作?
    【微信小程序开发】小程序版的防抖节流应该怎么写
    终于盼到了,Python 数据科学速查表中文版来了
    工控 UI 风格美轮美奂
    【校招VIP】前端计算机网络之webSocket相关
    Linux安装JDK和Tomcat
    计算机毕业设计Java校园课室资源预约系统设计与实现(系统+源码+mysql数据库+lw文档)
    信号的概念
  • 原文地址:https://blog.csdn.net/m0_37540696/article/details/127743794