• Activiti简单介绍


    在这里插入图片描述

    前言:基本上所有的业务都有审批环节,我们做需求的时候肯定也写过很多有关审批的代码,我接触的基本都是在自己的表中维护关于审批的字段,并没有使用开源组件进行实现,所以想学习一下,现在关于工作流的开源软件主要是activiti、flowable、camunda,activiti市面现存用量还是挺大的,需要了解一下。

    1. 在数据库中新建activiti4库,执行如下代码
    	/**
         * 生成Activiti的相关的表结构
         */
        @Test
        public void test01(){
            // 使用classpath下的activiti.cfg.xml中的配置来创建 ProcessEngine对象
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            System.out.println(engine);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    生成如下表:
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    2. 利用actiBPM插件生成流程图
    actiBPM插件不能在新版本的idea中使用,因为高版本idea不兼容这个插件,只能在旧版本的idea和eclipse中使用,可以在eclipse中使用插件生成bpmn和png文件,然后将文件拷贝到idea中使用。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    点击General和Main config进行具体设置
    在这里插入图片描述

    在这里插入图片描述

    保存时可能不会自动生成png文件,可以右键,有选项可以生成

    1. 图标
      Palette(画板)
      Connection—连接
      Event—事件
      Task—任务
      Gateway—网关
      Container—容器
      Boundary event—边界事件
      Intermediate event- -中间事件

    2. 流程部署

    /**
         * 实现文件的单个部署
         */
        @Test
        public void test03(){
            // 1.获取ProcessEngine对象
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 2.获取RepositoryService进行部署操作
            RepositoryService service = engine.getRepositoryService();
            // 3.使用RepositoryService进行部署操作
            Deployment deploy = service.createDeployment()
                    .addClasspathResource("bpmn/evection.bpmn") // 添加bpmn资源
                    .addClasspathResource("bpmn/evection.png") // 添加png资源
                    .name("出差申请流程-2")
                    .deploy();// 部署流程
            // 4.输出流程部署的信息
            System.out.println("流程部署的id:" + deploy.getId());
            System.out.println("流程部署的名称:" + deploy.getName());
        }
    
        /**
         * 通过一个zip文件来部署操作
         */
        @Test
        public void test04(){
            // 定义zip文件的输入流
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("bpmn/evection.zip");
            // 对 inputStream 做装饰
            ZipInputStream zipInputStream = new ZipInputStream(inputStream);
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            RepositoryService repositoryService = engine.getRepositoryService();
            Deployment deploy = repositoryService.createDeployment()
                    .addZipInputStream(zipInputStream)
                    .name("出差申请流程")
                    .deploy();
            // 4.输出流程部署的信息
            System.out.println("流程部署的id:" + deploy.getId());
            System.out.println("流程部署的名称:" + 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
    • 36
    • 37
    • 38
    • 39
    • 40

    在数据库中查看数据
    act_re_deployment: 流程定义部署表,每部署一次就增加一条记录
    act_re_procdef :流程定义表,部署每个新的流程定义都会在这张表中增加一条记录
    act_ge_bytearray :流程资源表,流程部署的 bpmn文件和png图片会保存在该表中
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    5. 启动流程实例
    流程定义部署在Activiti后就可以通过工作流管理业务流程,也就是说上边部署的出差申请流程可以使用
    了。
    针对该流程,启动一个流程表示发起一个新的出差申请单,这就相当于Java类和Java对象的关系,类定
    义好了后需要new创建一个对象使用,当然可以new出多个对象来,对于出差申请流程,张三可以发起
    一个出差申请单需要启动一个流程实例。

    /**
         * 启动一个流程实例
         */
        @Test
        public void test05(){
            // 1.创建ProcessEngine对象
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 2.获取RuntimeService对象
            RuntimeService runtimeService = engine.getRuntimeService();
            // 3.根据流程定义的id启动流程
            String id= "evection";
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(id);
            // 4.输出相关的流程实例信息
            System.out.println("流程定义的ID:" + processInstance.getProcessDefinitionId());
            System.out.println("流程实例的ID:" + processInstance.getId());
            System.out.println("当前活动的ID:" + processInstance.getActivityId());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    启动流程实例涉及到的表结构
    act_hi_actinst 流程实例执行历史
    act_hi_identitylink 流程的参与用户的历史信息
    act_hi_procinst 流程实例历史信息
    act_hi_taskinst 流程任务历史信息
    act_ru_execution 流程执行信息
    act_ru_identitylink 流程的参与用户信息
    act_ru_task 任务信息

    1. 任务查询
        /**
         * 任务查询
         */
        @Test
        public void test06(){
            String assignee ="zhansan";
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 任务查询 需要获取一个 TaskService 对象
            TaskService taskService = engine.getTaskService();
            // 根据流程的key和任务负责人 查询任务
            List<Task> list = taskService.createTaskQuery()
                    .processDefinitionKey("evection")
                    .taskAssignee(assignee)
                    .list();
            // 输出当前用户具有的任务
            for (Task task : list) {
                System.out.println("流程实例id:" + task.getProcessInstanceId());
                System.out.println("任务id:" + task.getId());
                System.out.println("任务负责人:" + task.getAssignee());
                System.out.println("任务名称:" + task.getName());
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    1. 任务处理
      处理一个任务,任程流向下一个节点,直到流程走完
    /**
         * 流程任务的处理
         */
        @Test
        public void test07(){
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            TaskService taskService = engine.getTaskService();
            Task task = taskService.createTaskQuery()
                    .processDefinitionKey("evection")
                    .taskAssignee("zhansan")
                    .singleResult();
            // 完成任务
            taskService.complete(task.getId());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 查询流程的定义
    /**
         * 查询流程的定义
         */
        @Test
        public void test08(){
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            RepositoryService repositoryService = engine.getRepositoryService();
            // 获取一个 ProcessDefinitionQuery对象 用来查询操作
            ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
            List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("evection")
                    .orderByProcessDefinitionVersion() // 安装版本排序
                    .desc() // 倒序
                    .list();
            // 输出流程定义的信息
            for (ProcessDefinition processDefinition : list) {
                System.out.println("流程定义的ID:" + processDefinition.getId());
                System.out.println("流程定义的name:" + processDefinition.getName());
                System.out.println("流程定义的key:" + processDefinition.getKey());
                System.out.println("流程定义的version:" + processDefinition.getVersion());
                System.out.println("流程部署的id:" + processDefinition.getDeploymentId());
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述
    9. 流程的删除

    /**
         * 删除流程
         */
        @Test
        public void test09(){
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            RepositoryService repositoryService = engine.getRepositoryService();
            // 删除流程定义,如果该流程定义已经有了流程实例启动则删除时报错
            repositoryService.deleteDeployment("20001");
            // 设置为TRUE 级联删除流程定义,及时流程有实例启动,也可以删除,设置为false 非级联删除操作。
            //repositoryService.deleteDeployment("12501",true);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 读取数据库中的资源文件
     /**
         * 读取数据库中的资源文件
         */
        @Test
        public void test10() throws Exception{
            // 1.得到ProcessEngine对象
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 2.获取RepositoryService对象
            RepositoryService repositoryService = engine.getRepositoryService();
            // 3.得到查询器
            ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionKey("evection")
                    .singleResult();
            // 4.获取流程部署的id
            String deploymentId = definition.getDeploymentId();
            // 5.通过repositoryService对象的相关方法 来获取图片信息和bpmn信息
            // png图片
            InputStream pngInput = repositoryService
                    .getResourceAsStream(deploymentId, definition.getDiagramResourceName());
            // bpmn 文件的流
            InputStream bpmnInput = repositoryService
                    .getResourceAsStream(deploymentId, definition.getResourceName());
            // 6.文件的保存
            File filePng = new File("D:/document2/study_doc/java_20220317_234441/Activiti资料/ActivitiDemo01/src/main/resources/bpmn/evection.png");
            File fileBpmn = new File("D:/document2/study_doc/java_20220317_234441/Activiti资料/ActivitiDemo01/src/main/resources/bpmn/evection.bpmn");
            OutputStream pngOut = new FileOutputStream(filePng);
            OutputStream bpmnOut = new FileOutputStream(fileBpmn);
    
            IOUtils.copy(pngInput,pngOut);
            IOUtils.copy(bpmnInput,bpmnOut);
    
            pngInput.close();
            pngOut.close();
            bpmnInput.close();
            bpmnOut.close();
        }
    
    • 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
    1. 流程的历史信息
        /**
         * 流程历史信息查看
         */
        @Test
        public void test11(){
            ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
            // 查看历史信息我们需要通过 HistoryService来实现
            HistoryService historyService = engine.getHistoryService();
            // 获取 actinst 表的查询对象
            HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
            instanceQuery.processDefinitionId("evection:1:12504");
            instanceQuery.orderByHistoricActivityInstanceStartTime().desc();
            List<HistoricActivityInstance> list = instanceQuery.list();
            // 输出查询的结果
            for (HistoricActivityInstance hi : list) {
                System.out.println(hi.getActivityId());
                System.out.println(hi.getActivityName());
                System.out.println(hi.getActivityType());
                System.out.println(hi.getAssignee());
                System.out.println(hi.getProcessDefinitionId());
                System.out.println(hi.getProcessInstanceId());
                System.out.println("-----------------------");
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    1. 网关
      在这里插入图片描述

    12.1 排他网关:总经理审批和财务审批只会有一个节点会被执行
    在这里插入图片描述

    12.2 并行网关:技术经理和项目经理都必须执行,不需指定执行的先后顺序,常用在会签任务

    在这里插入图片描述

    12.3 包含网关:相当于综合了排他网关和并行网关,人事经理必须执行,项目经理和技术经理只执行一个,然后执行者两个后会签成功流向下个节点
    在这里插入图片描述
    12.4 事件网关:专门为中间捕获事件设置的,允许设置多个输出流指向多个不同的中间捕获事件。当流程执行到事
    件网关后,流程处于等待状态,需要等待抛出事件才能将等待状态转换为活动状态。

    资料、代码下载来自up主波哥,在此感谢,链接:https://pan.baidu.com/s/18h8tvkmMmm8RNp00Q9oZlg 提取码:boge

  • 相关阅读:
    基于JAVA的校园二手交易网站的设计与实现参考【数据库设计、源码、开题报告】
    CentOS 7 安装RabbitMQ
    了解WEB
    遗传算法(GA)学习 || 原理、本质、代码、例题
    如何链接多个modbus_tcp设备,并将设备数据写入同一个modbusSlave,以便外部客户端获取所有链接设备的数据。
    深入探索图像处理:从基础到高级应用
    Python图像处理丨图像的灰度线性变换
    labview实现仪器的控制visa
    leetcode做题笔记141. 环形链表
    Kafka - 04 Java客户端实现消息发送和订阅
  • 原文地址:https://blog.csdn.net/weixin_43024834/article/details/126557078