Activiti7_使用

2024-05-27 14:44
文章标签 使用 activiti7

本文主要是介绍Activiti7_使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Activiti7_使用

  • 一、Activiti7
  • 二、绘制工作流
  • 三、通过代码部署流程,再对流程进行实例化,完整运行一遍流程即可
  • 四、在springbooot中使用


一、Activiti7

  1. 为了实现后端的咨询流转功能,学习Activiti7,记录下使用的过程及遇到的问题

二、绘制工作流

  1. 使用spring3的后端项目为基础,开发工具idea 2023.3.2,jdk,jdk17。
    点此链接link去idea官网下载插件Activiti BPMN,在idea的Settings里Plugins使用install plugin from disk把刚才的jar包导进去
  2. 在bpmn文件夹下创建bpmn文件:
    !在这里插入图片描述
  3. 使用插件以画图形式编辑bpmn:
    在这里插入图片描述
    主要使用了三种部件:开始、任务、结束在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
任务的内容填写如下,连线按住右上角的箭头拖拽到目标即可,里面的${user}表明设置为user的变量,一会可以在使用的时候绑定用户:
在这里插入图片描述
其中的分支路线我们直接使用两个互斥条件判断,不使用排他网关:
在这里插入图片描述在这里插入图片描述

排他网关(也叫异或(XOR)网关,或叫基于数据的排他网关),用来在流程中实现决策。 当流程执行到这个网关,所有分支都会判断条件是否为 true,如果为 true 则执行该分支,注意,排他网关只会选择一个为 true 的分支执行。 (即使有两个分支条件都为 true, 排他网关也会只选择一条分支去执行)。如果从网关出去的线所有条件都不满足则系统抛出异常。说明 :经过排他网关必须要有一条且只有一条分支走。
bpmn文件绘制完成了,保存成同名png文件:在这里插入图片描述

  1. 完整的bpmn代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<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:activiti="http://activiti.org/bpmn" 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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef"><process id="consult" name="consult" isExecutable="true"><startEvent id="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1"/><userTask id="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4" name="用户填写咨询表单" activiti:assignee="${user}"><documentation>用户填写咨询表单</documentation></userTask><userTask id="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854" name="管理员指定业务人员" activiti:assignee="${admin}"><documentation>管理员指定业务人员</documentation></userTask><userTask id="sid-7b539102-6d65-479a-9958-5259a84c28b1" name="业务人员回复" activiti:assignee="${busPerson}"><documentation>业务人员回复</documentation></userTask><userTask id="sid-3af84618-4ba9-4686-a97f-6db4da96e916" name="管理员决定是否公示" activiti:assignee="${admin}"><documentation>管理员决定是否公示</documentation></userTask><endEvent id="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"/><sequenceFlow id="sid-c2da4d94-8eac-4acd-9cb0-16328237a136" sourceRef="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1" targetRef="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4"/><sequenceFlow id="sid-5be6635f-b5ef-4e0e-98af-1b35c6e085ae" sourceRef="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4" targetRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854"/><sequenceFlow id="sid-5dc1e8b5-e2bc-45b7-b559-bffe2d3b5c24" sourceRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854" targetRef="sid-7b539102-6d65-479a-9958-5259a84c28b1"/><sequenceFlow id="sid-c3c3594c-d7d1-462f-b057-59b12dbeb190" sourceRef="sid-3af84618-4ba9-4686-a97f-6db4da96e916" targetRef="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"/><sequenceFlow id="sid-8a860827-e9ad-4c62-b931-939d312ddcd8" sourceRef="sid-7b539102-6d65-479a-9958-5259a84c28b1" targetRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854"><conditionExpression>${evection.num&gt;1}</conditionExpression></sequenceFlow><sequenceFlow id="sid-f4dc4277-d16a-415e-9cac-fe51d1c6ee65" sourceRef="sid-7b539102-6d65-479a-9958-5259a84c28b1" targetRef="sid-3af84618-4ba9-4686-a97f-6db4da96e916"><conditionExpression>${evection.num&lt;=1}</conditionExpression></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_consult"><bpmndi:BPMNPlane bpmnElement="consult" id="BPMNPlane_consult"><bpmndi:BPMNShape id="shape-b1791cfb-c3c9-42a9-9bd8-b7e0a8906f99" bpmnElement="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1"><omgdc:Bounds x="-15.0" y="-120.0" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-33324ea7-5905-4b2a-b615-2bfe666a0117" bpmnElement="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4"><omgdc:Bounds x="-50.0" y="-60.0" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-955afe5f-f9b7-40f0-887f-70aeb5afc173" bpmnElement="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854"><omgdc:Bounds x="-50.0" y="40.0" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-7a2e9e19-c268-4a46-af9c-aa6621dd9b86" bpmnElement="sid-7b539102-6d65-479a-9958-5259a84c28b1"><omgdc:Bounds x="-50.0" y="150.0" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-86aead71-8e5b-4de3-8d8c-ca5f0dcc63ea" bpmnElement="sid-3af84618-4ba9-4686-a97f-6db4da96e916"><omgdc:Bounds x="-50.0" y="255.0" width="100.0" height="80.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-1d13b250-9f5c-42db-a745-482b2c9acf56" bpmnElement="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"><omgdc:Bounds x="-15.0" y="360.0" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-c60fd374-56ca-4630-9f88-c9d61baa048b" bpmnElement="sid-c2da4d94-8eac-4acd-9cb0-16328237a136"><omgdi:waypoint x="0.0" y="-90.0"/><omgdi:waypoint x="0.0" y="-60.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-4a1da47a-a9b5-4db2-a8a9-002220e5c52a" bpmnElement="sid-5be6635f-b5ef-4e0e-98af-1b35c6e085ae"><omgdi:waypoint x="0.0" y="20.0"/><omgdi:waypoint x="0.0" y="40.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-3d9c4ead-a6cd-4aa2-82c7-ad1f20171327" bpmnElement="sid-5dc1e8b5-e2bc-45b7-b559-bffe2d3b5c24"><omgdi:waypoint x="0.0" y="120.0"/><omgdi:waypoint x="0.0" y="150.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-2116f8bb-51a7-4c43-a48b-7c4954868724" bpmnElement="sid-c3c3594c-d7d1-462f-b057-59b12dbeb190"><omgdi:waypoint x="0.0" y="335.0"/><omgdi:waypoint x="0.0" y="360.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-ce0e6fc3-032f-4333-83ec-7807846b046f" bpmnElement="sid-8a860827-e9ad-4c62-b931-939d312ddcd8"><omgdi:waypoint x="-50.0" y="190.0"/><omgdi:waypoint x="-125.0" y="135.0"/><omgdi:waypoint x="-50.0" y="80.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-87fa2036-1930-4551-bede-92f275696c68" bpmnElement="sid-f4dc4277-d16a-415e-9cac-fe51d1c6ee65"><omgdi:waypoint x="0.0" y="230.0"/><omgdi:waypoint x="0.0" y="242.5"/><omgdi:waypoint x="0.0" y="255.0"/></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>

三、通过代码部署流程,再对流程进行实例化,完整运行一遍流程即可

需要序列化一个evection:在这里插入图片描述

package com.sumo.ipd;import java.io.Serializable;public class Evection implements Serializable {public int getNum() {return num;}public void setNum(int num) {this.num = num;}private int num;
}

在test里面创建ActivitiDemo类,内容:

package com.sumo.ipd;import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ActivitiDemo {/*** 部署流程定义测试,查询,删除*/@Testpublic void DeployTest() {// 1. 创建ProcessEngine流程引擎对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2、得到RepositoryService实例RepositoryService repositoryService = processEngine.getRepositoryService();// 3、使用RepositoryService进行部署,定义一个流程名字,把bpmn和png部署到数据库中Deployment deployment = repositoryService.createDeployment()    // 创建一个部署流程.name("咨询流程")                                    // 给部署流程命名.addClasspathResource("bpmn/consult.bpmn20.xml")        // 添加类路径下的资源文件.addClasspathResource("bpmn/consult.png").deploy();                                                // 执行流程部署// 4、输出部署信息System.out.println("流程部署id:" + deployment.getId());System.out.println("流程部署名称:" + deployment.getName());}@Testpublic void queryProceccDefinition() {// 流程定义keyString processDefinitionKey = "consult";// 创建ProcessEngine流程引擎对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 获取repositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();// 查询流程定义ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();//遍历查询结果List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(processDefinitionKey).orderByProcessDefinitionVersion().desc().list();for (ProcessDefinition processDefinition : list) {System.out.println("------------------------");System.out.println(" 流 程 部 署 id : " +processDefinition.getDeploymentId());System.out.println("流程定义id: " + processDefinition.getId());System.out.println("流程定义名称: " + processDefinition.getName());System.out.println("流程定义key: " + processDefinition.getKey());System.out.println("流程定义版本: " + processDefinition.getVersion());}}@Testpublic void deleteDeployment() {// 流程部署idString deploymentId = "47501";// 通过流程引擎获取repositoryServiceProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();
//        删除启动的流程实例RuntimeService runtimeService = processEngine.getRuntimeService();runtimeService.deleteProcessInstance("50001","用户撤销");//删除流程定义, 如果该流程定义已有流程实例启动则删除时出错//repositoryService.deleteDeployment(deploymentId);//设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设//置为false非级别删除方式,如果流程repositoryService.deleteDeployment(deploymentId, true);}/*** 启动流程实例*/@Testpublic void startProcessTest() {//businessKey用于绑定外部任务表单的idString businessKey = "1";// 1、创建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2、获取RunTimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();// 流程变量的mapMap<String, Object> variables = new HashMap<>();// 设定任务的负责人variables.put("user", "523097198902120431");variables.put("admin", "123456");variables.put("busPerson", "123456789");Evection evection = new Evection();evection.setNum(3);// 把流程变量的pojo放入mapvariables.put("evection",evection);// 3、根据流程定义Id启动流程,并获取流程实例ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("consult", businessKey, variables);// 输出内容System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());System.out.println("流程实例id:" + processInstance.getId());System.out.println("当前活动Id:" + processInstance.getActivityId());System.out.println("businessKey==" + processInstance.getBusinessKey());}/*** 查询当前个人待执行的任务*/public void findTaskListTest(String assignee) {// 1.创建流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2.获取TaskServiceTaskService taskService = processEngine.getTaskService();// 3.根据流程key 和 任务负责人 查询任务List<Task> list = taskService.createTaskQuery().processDefinitionKey("consult")        //流程Key.taskAssignee(assignee)                    //只查询当前任务负责人的任务.list();Task task = taskService.createTaskQuery()
//                .processInstanceId("15001")            //流程实例id.processDefinitionKey("consult")     //流程Key.taskAssignee(assignee)                 //只查询当前任务负责人的任务.singleResult();String processInstanceId = task.getProcessInstanceId();// 2、获取RunTimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();String businessKey = processInstance.getBusinessKey();//        list.forEach(task -> {System.out.println("-----------------------------------------");System.out.println("流程实例id:" + task.getProcessInstanceId());System.out.println("任务id:" + task.getId());System.out.println("任务负责人:" + task.getAssignee());System.out.println("任务名称:" + task.getName());System.out.println("businessKey==" + businessKey);
//        });Evection eve = (Evection)taskService.getVariable(task.getId(), "evection");System.out.println(eve.getNum());System.out.println("获取流程变量成功");}/*** 完成个人代办任务及查询下一步*/@Testpublic void completTaskTest() {findTaskListTest("523097198902120431");completTask("523097198902120431");findTaskListTest("123456");completTask2("123456");findTaskListTest("123456789");completTask("123456789");findTaskListTest("123456");completTask("123456");}/*** 普通的完成任务* @param assignee*/public void completTask(String assignee) {// 1.创建流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2. 获取TaskService实例TaskService taskService = processEngine.getTaskService();// 3.根据流程key 和 任务的负责人 查询任务Task task = taskService.createTaskQuery().processDefinitionKey("consult")     //流程Key.taskAssignee(assignee)                 //只查询当前任务负责人的任务.singleResult();System.out.println("流程实例id:" + task.getProcessInstanceId());System.out.println("任务id:" + task.getId());System.out.println("任务负责人:" + task.getAssignee());System.out.println("任务名称:" + task.getName()+" 完成!");// 4.完成待办任务,参数:任务idtaskService.complete(task.getId());}/*** 在完成任务时修改变量调整分支走向* @param assignee*/public void completTask2(String assignee) {// 1.创建流程引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2. 获取TaskService实例TaskService taskService = processEngine.getTaskService();// 3.根据流程key 和 任务的负责人 查询任务Task task = taskService.createTaskQuery().processDefinitionKey("consult")     //流程Key.taskAssignee(assignee)                 //只查询当前任务负责人的任务.singleResult();System.out.println("流程实例id:" + task.getProcessInstanceId());System.out.println("任务id:" + task.getId());System.out.println("任务负责人:" + task.getAssignee());System.out.println("任务名称:" + task.getName()+" 完成!");// 流程变量的mapMap<String, Object> variables = new HashMap<>();Evection evection = new Evection();evection.setNum(1);// 把流程变量的pojo放入mapvariables.put("evection",evection);// 4.完成待办任务,参数:任务idtaskService.complete(task.getId(),variables);}/*** 如果一个流程中有多个任务,可以用list*/@Testpublic void completeTask3() {// 获取引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 获取操作任务的服务 TaskServiceTaskService taskService = processEngine.getTaskService();// 完成 经理 '李四' 的任务List<Task> tasks = taskService.createTaskQuery().processDefinitionKey("evection").taskAssignee("李四").list();  // 多个任务,用listfor (Task task : tasks) {if (true) {// 判断是哪任务System.out.println("流程实例id=" + task.getProcessInstanceId());System.out.println("任务Id=" + task.getId());System.out.println("任务负责人=" + task.getAssignee());System.out.println("任务名称=" + task.getName());taskService.complete(task.getId());}}}
}

运行ActivitiDemo完整运行一遍流程:
1DeployTest部署流程
2startProcessTest启动流程实例
3completTaskTest运行一遍流程

四、在springbooot中使用

依赖会出现报错,需要修改pom.xml

  1. 使用log4j会和springboot本身的logback冲突,排除logback
		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><artifactId>spring-boot-starter-logging</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions></dependency>
  1. 已经有mybatis了,把不用的注释掉在这里插入图片描述

  2. 排除slf4j-log4j12的log4j,避免和外面的log4j冲突

		<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version><exclusions><!-- 排除slf4j-log4j12的log4j,避免和外面的log4j冲突 --><exclusion><artifactId>log4j</artifactId><groupId>log4j</groupId></exclusion></exclusions></dependency>

这篇关于Activiti7_使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1007773

相关文章

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

Pydantic中Optional 和Union类型的使用

《Pydantic中Optional和Union类型的使用》本文主要介绍了Pydantic中Optional和Union类型的使用,这两者在处理可选字段和多类型字段时尤为重要,文中通过示例代码介绍的... 目录简介Optional 类型Union 类型Optional 和 Union 的组合总结简介Pyd

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准