工作流之Activiti7 和BPMN讲解

2024-09-03 08:44

本文主要是介绍工作流之Activiti7 和BPMN讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1 Activiti
    • 1.1 简介
    • 1.2 BPMN
      • 1.2.1 简介
      • 1.2.2 符号
    • 1.3 准备工作
      • 1.3.1 安装插件
        • 1.3.1.1 插件
        • 1.3.1.2 本地网页
      • 1.3.2 pom依赖
      • 1.3.3 添加配置
      • 1.3.4 表介绍
      • 1.3.5 常用Service服务介绍
    • 1.4 无校验操作流程
      • 1.4.1 部署&查看文件
        • 1.4.1.1 单个文件部署方式
        • 1.4.1.2 静态类部署
        • 1.4.1.3 压缩包部署方式
        • 1.4.1.4 查看文件
      • 1.4.2 启动流程实例和查询
      • 1.4.3 查询任务和历史
      • 1.4.4 处理当前任务
      • 1.4.5 流程定义
    • 1.5 新版校验操作
      • 1.5.1 配置Security用户
      • 1.5.2 操作
      • 1.5.3 报错 Process definition with the given id:xxx belongs to a different application version
    • 1.6 Activiti 7.1.0.M6之后

1 Activiti

1.1 简介

Activiti 是一个开源的工作流和业务流程管理 (BPM) 平台,旨在帮助开发者和企业自动化业务流程。它提供了一整套工具,用于定义、执行、监控和优化业务流程。Activiti 支持 BPMN 2.0 标准,具有强大的扩展能力和易用性,适用于各种规模的组织和复杂的业务需求。
官方网站:https://www.activiti.org
https://mp.weixin.qq.com/s/Xa3yIp1FRYpQF87lmf91OA

1.2 BPMN

1.2.1 简介

BPM(Business Process Management) 即业务流程管理,是一种规范化的构造端到端的业务流程,以持续提高组织业务效率

BPMN(Business Process Model AndNotation) 即业务流程模型和符号,是一套标准的业务流程建模符号,使用 BPMN 提供的符号可以创建业务流程。Activit 就是使用 BPMN 进行流程建模、流程执行管理的
BPMN2.0 是业务流程建模符号 2.0 的缩写,它由 Business Process Management Initiative 这个非营利协会创建并不断发展。BPMN2.0 是使用一些符号来明确业务流程设计流程图的一套符号规范,能增进业务建模时的沟通效率。

1.2.2 符号

BPMN2.0 的基本符号主要包含

  • 事件 Event
    开始:表示一个流程的开始
    中间:发生的开始和结束事件之间,影响处理的流程
    结束:表示该过程结束
    在这里插入图片描述

  • 活动 Activities
    活动是工作或任务的一个通用术语。一个活动可以是一个任务,还可以是一个当前流程的子处理流程;其次,还可以为活动指定不同的类型。常见活动如下:
    在这里插入图片描述

  • 网关 GateWay
    用于表示流程的分支与合并,有几种常用网关需要了解:
    在这里插入图片描述
    排他网关:只有一条路径会被选择,基于条件选择单一路径
    并行网关:无条件并行执行所有路径
    包容网关:可以同时执行多条线路,也可以在网关上设置条件,基于条件可以选择多个路径同时执行
    事件网关:基于外部事件的发生来决定路径选择,即专门为中间捕获事件设置的,允许设置多个输出流指向多个不同的中间捕获事件。当流程执行到事件网关后,流程处于等待状态,需要等待抛出事件才能将等待状态转换为活动状态

  • 流向 Flow
    流是连接两个流程节点的连线,常见的流向包含以下几种:
    顺序流:用一个带实心箭头的实心线表示,用于指定活动执行的顺序
    信息流:用一条带箭头的虚线表示,用于描述两个独立的业务参与者(业务实体/业务角色)之间发送和接受的消息流动
    关联:用一根带有线箭头的点线表示,用于将相关的数据、文本和其他人工信息与流对象联系起来。用于展示活动的输入和输出
    在这里插入图片描述

  • 边界事件(Boundary Events
    边界事件是一种特殊的事件,它附加在流程元素(如任务、子流程等)上,用于捕捉特定事件并对其进行处理。边界事件通常用于中断或处理任务的异常情况,或者处理流程中某些特定的事件场景。

    • 中断任务: 当绑定在某个任务上的边界事件被触发时,任务可以被中断,流程将根据边界事件的定义跳转到其他节点或执行特定的操作。这通常用于处理异常情况,如错误、超时等。
    • 捕获事件: 边界事件可以用来捕捉在任务执行过程中发生的特定事件,例如错误事件(Error Event)、定时事件(Timer Event)、消息事件(Message Event)等。当这些事件发生时,流程会从当前任务转移到处理该事件的流程路径。
    • 处理子流程: 在嵌套子流程中,边界事件可以用于在子流程内某个特定事件发生时触发相应的处理逻辑。

1.3 准备工作

1.3.1 安装插件

1.3.1.1 插件

IDEA版本小于等于2019,可使用Activiti插件actiBPM,如果获取不到插件市场获取:https://plugins.jetbrains.com/plugin/7429-actibpm
否则使用Activiti BPMN visualizer
在这里插入图片描述
假如要画一个请假的 activiti 流程图,使用 Idea 安装 actiBPM 插件,创建该流程图,文件命名apply.mpmn,实现请假流程的二级审批能力,右键点击view bpmn diagram 才会有图示出来
在这里插入图片描述

1.3.1.2 本地网页

如果觉得插件画图麻烦,可以用 Activiti ModelerActiviti Modeler 是 Activiti 官方提供的一款在线流程设计的前端插件,开发人员可以方便在线进行流程设计,保存流程模型,部署至流程定义等等

下载activiti-explorer,官网下载:Get started | Activiti
解压activiti-5.22.0.zip,在activiti-5.22.0\wars目录下获取activiti-explorer.war
启动路径:双击startup.bat
在这里插入图片描述

访问activiti-explorer:http://localhost:8080/activiti-explorer
默认登录账号:kermit kermit

1.3.2 pom依赖

<!--引入activiti的springboot启动器 -->
<dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId><version>7.1.0.M6</version><exclusions><exclusion><artifactId>mybatis</artifactId><groupId>org.mybatis</groupId></exclusion></exclusions><!-- 不加如下依赖报错:'org.springframework.security.core.userdetails.UserDetailsService' that could not be found. --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
<!-- 不加可能报错:Consider defining a bean of type 'javax.sql.DataSource' in your configuration --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><!-- 或者使用druid-spring-boot-starter --></dependency>
</dependency>

说明:Activiti7SpringBoot整合后,默认集成了SpringSecurity安全框架,当前项目已经集成过了SpringSecurity,后续案例设置审批人时都必须是系统用户,Activiti框架会检查用户是否存在,否则会出现异常

1.3.3 添加配置

数据源项目已经添加,只需要如下配置即可

spring:datasource:url: jdbc:mysql://localhost:3316/activiti?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghaiusername: xxxxpassword: xxxxdriver-class-name: com.mysql.cj.jdbc.Driveractiviti:#    false:默认,数据库表不变,但是如果版本不对或者缺失表会抛出异常(生产使用)#    true:表不存在,自动创建(开发使用)#    create_drop: 启动时创建,关闭时删除表(测试使用)#    drop_create: 启动时删除表,在创建表 (不需要手动关闭引擎)database-schema-update: true#监测历史表是否存在,activities7默认不开启历史表db-history-used: true#none:不保存任何历史数据,流程中这是最高效的#activity:只保存流程实例和流程行为#audit:除了activity,还保存全部的流程任务以及其属性,audit为history默认值#full:除了audit、还保存其他全部流程相关的细节数据,包括一些流程参数history-level: full#校验流程文件,默认校验resources下的process 文件夹的流程文件check-process-definitions: false# 定义.bpmn文件的位置process-definition-location-prefix: classpath:/process/

1.3.4 表介绍

启动项目,即可生成项目数据库表
在这里插入图片描述
Activiti 的运行支持必须要有这 25 张表的支持,主要是在业务流程运行过程中,记录参与流程的用户主体,用户组信息,以及流程的定义,流程执行时的信息,和流程的历史信息等等

表的命名规则和作用:

  • Activiti 的表都以 act_ 开头,紧接着是表示表的用途的两个字母标识,也和 Activiti 所提供的服务的 API 对应:
    • ACT_RE:RE 表示 repository,这个前缀的表包含了流程定义和流程静态资源 (图片、规则、等等)
    • ACT_RU:RU 表示 runtime,这些表运行时,会包含流程实例、任务、变量、异步任务等流程业务进行中的数据。Activiti 只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录。这样表就可以一直保持很小的体积,并且速度很快
    • ACT_HI:HI 表示 history,这些表包含一些历史数据,比如历史流程实例、变量、任务等等
    • ACT_GE:GE 表示 general,通用数据

Activiti 数据表介绍

表分类表名解释
一般数据
[ACT_GE_BYTEARRAY]通用的流程定义和流程资源
[ACT_GE_PROPERTY]系统相关属性
流程历史记录
[ACT_HI_ACTINST]历史的流程实例
[ACT_HI_ATTACHMENT]历史的流程附件
[ACT_HI_COMMENT]历史的说明性信息
[ACT_HI_DETAIL]历史的流程运行中的细节信息
[ACT_HI_IDENTITYLINK]历史的流程运行过程中用户关系
[ACT_HI_PROCINST]历史的流程实例
[ACT_HI_TASKINST]历史的任务实例
[ACT_HI_VARINST]历史的流程运行中的变量信息
流程定义表
[ACT_RE_DEPLOYMENT]部署单元信息
[ACT_RE_MODEL]模型信息
[ACT_RE_PROCDEF]已部署的流程定义
运行实例表
[ACT_RU_EVENT_SUBSCR]运行时事件
[ACT_RU_EXECUTION]运行时流程执行实例
[ACT_RU_IDENTITYLINK]运行时用户关系信息,存储任务节点与参与者的相关信息
[ACT_RU_JOB]运行时作业
[ACT_RU_TASK]运行时任务
[ACT_RU_VARIABLE]运行时变量表

1.3.5 常用Service服务介绍

各个 Service 的实现类,这些服务是 Activiti 的底层核心 API,提供了对工作流引擎内部的细粒度控制。它们是 Activiti 5 和 6 中主要使用的服务,提供了更低级别的操作接口:

  • RepositoryService
    Activiti 的资源管理类,该服务负责部署流程定义,管理流程资源。在使用 Activiti 时,一开始需要先完成流程部署,即将使用建模工具设计的业务流程图通过 RepositoryService 进行部署
  • RuntimeService
    Activiti 的流程运行管理类,用于开始一个新的流程实例,获取关于流程执行的相关信息。流程定义用于确定一个流程中的结构和各个节点间行为,而流程实例则是对应的流程定义的一个执行,可以理解为 Java 中类和对象的关系
  • TaskService
    Activiti 的任务管理类,用于处理业务运行中的各种任务,例如查询分给用户或组的任务、创建新的任务、分配任务、确定和完成一个任务
  • HistoryService
    Activiti 的历史管理类,可以查询历史信息。执行流程时,引擎会保存很多数据,比如流程实例启动时间、任务的参与者、完成任务的时间、每个流程实例的执行路径等等。这个服务主要通过查询功能来获得这些数据
  • ManagementService
    Activiti 的引擎管理类,提供了对 Activiti 流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于 Activiti 系统的日常维护

Activiti7后新增服务:

  • TaskRuntime:这个服务主要用于管理用户任务。通过它,可以查询任务、完成任务、分配任务、认领任务等。这些操作是围绕任务管理的高层次抽象,开发人员可以更加方便地与任务进行交互,而无需直接处理底层的 API 调用。
  • ProcessRuntime:这个服务用于管理流程实例。可以通过它启动流程、查询流程实例、暂停和恢复流程等。ProcessRuntime 提供了一个更简单的方式来处理流程的生命周期管理。

1.4 无校验操作流程

将画好的流程图部署到activiti数据库中,就是流程定义部署。通过调用activiti的api将流程定义的bpmn和png两个文件一个一个添加部署到activiti中,也可以将两个文件打成zip包进行部署。

1.4.1 部署&查看文件

流程定义部署后操作activiti的3张表如下:

  • act_re_deployment:流程定义部署表,每部署一次增加一条记录
  • act_re_procdef:流程定义表,部署每个新的流程定义都会在这张表中增加一条记录
  • act_ge_bytearray:流程资源表
1.4.1.1 单个文件部署方式

@SpringBootTest
public class ProcessTest {//注入RepositoryService@Autowiredprivate RepositoryService repositoryService;/*** 单个文件部署方式*/@Testpublic void deployProcess() {//流程部署Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/qingjia.bpmn20.xml")// 如果报错找不到图片在pom里面添加: <include>**/*.png</include>.addClasspathResource("process/qingjia.png").name("请假申请流程").deploy();System.out.println(deploy.getId());System.out.println(deploy.getName());}
}
1.4.1.2 静态类部署
	@Testpublic void testDeployment(){
//        1、创建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        2、得到RepositoryService实例RepositoryService repositoryService = processEngine.getRepositoryService();
//        3、使用RepositoryService进行部署Deployment deployment = repositoryService.createDeployment().addClasspathResource("process/qingjia.bpmn") // 添加bpmn资源 .name("请假申请流程").deploy();
//        4、输出部署信息System.out.println("流程部署id:" + deployment.getId());System.out.println("流程部署名称:" + deployment.getName());}
1.4.1.3 压缩包部署方式
@Autowired
private RepositoryService repositoryService;
@Test
public void deployProcessByZip() {// 定义zip输入流InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("process/qingjia.zip");ZipInputStream zipInputStream = new ZipInputStream(inputStream);// 流程部署Deployment deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).name("请假申请流程").deploy();System.out.println("流程部署id:" + deployment.getId());System.out.println("流程部署名称:" + deployment.getName());
}
1.4.1.4 查看文件
@Test
public void  queryBpmnFile() throws IOException {
//得到查询器:ProcessDefinitionQuery,设置查询条件,得到想要的流程定义ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("qingjia").singleResult();
//通过流程定义信息,得到部署IDString deploymentId = processDefinition.getDeploymentId();
//  通过repositoryService的方法,实现读取图片信息和bpmn信息
//        png图片的流InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
//        bpmn文件的流InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
//  构造OutputStream流File file_png = new File("d:/qingjia.png");File file_bpmn = new File("d:/qingjia.bpmn");FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);FileOutputStream pngOut = new FileOutputStream(file_png);
//        7、输入流,输出流的转换IOUtils.copy(pngInput,pngOut);IOUtils.copy(bpmnInput,bpmnOut);
//        8、关闭流pngOut.close();bpmnOut.close();pngInput.close();bpmnInput.close();
}

1.4.2 启动流程实例和查询

将bpmn文件放到activiti的三张表中,好比是java中的一个类 流程实例:好比是java中的一个实例对象(一个流程定义可以对应多个流程实例),张三可以启动一个请假流程实例,李四也可以启动一个请假流程实例,他们互不影响

@Autowired
private RuntimeService runtimeService;@Test
public void startUpProcess() {//创建流程实例,我们需要知道流程定义的keyProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia");//输出实例的相关信息System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());System.out.println("流程实例id:" + processInstance.getId());System.out.println("当前活动Id:" + processInstance.getActivityId());
}

注意:使用startProcessInstanceByKey的方式不用在部署了,springboot会自动部署bpmn文件
操作数据表:

  • act_hi_actinst 流程实例执行历史
  • act_hi_identitylink 流程的参与用户历史信息
  • act_hi_procinst 流程实例历史信息
  • act_hi_taskinst 流程任务历史信息
  • act_ru_execution 流程执行信息
  • act_ru_identitylink 流程的参与用户信息
  • act_ru_task 任务信息
/*** 查询流程实例*/
@Test
public void queryProcessInstance() {List<ProcessInstance> list = runtimeService.createProcessInstanceQuery("qingjia").processDefinitionKey()//.list();for (ProcessInstance processInstance : list) {System.out.println("----------------------------");System.out.println("流程实例id:"+ processInstance.getProcessInstanceId());System.out.println("所属流程定义id:"+ processInstance.getProcessDefinitionId());System.out.println("是否执行完成:" + processInstance.isEnded());System.out.println("是否暂停:" + processInstance.isSuspended());System.out.println("当前活动标识:" + processInstance.getActivityId());System.out.println("业务关键字:"+processInstance.getBusinessKey());}
}

查看流程实例历史

/*** 查看历史信息*/
@Test
public void findHistoryInfo(){
//        获取 actinst表的查询对象HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
//        查询 actinst表,条件:根据 InstanceId 查询,查询一个流程的所有历史信息instanceQuery.processInstanceId("25001");
//        查询 actinst表,条件:根据 DefinitionId 查询,查询一种流程的所有历史信息
//        instanceQuery.processDefinitionId("myLeave:1:22504");
//        增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
//        查询所有内容List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
//        输出for (HistoricActivityInstance hi : activityInstanceList) {System.out.println(hi.getActivityId());System.out.println(hi.getActivityName());System.out.println(hi.getProcessDefinitionId());System.out.println(hi.getProcessInstanceId());System.out.println("<==========================>");}
}

1.4.3 查询任务和历史

每个节点都配置了Assignee,流程启动后,任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。

@Autowired
private TaskService taskService;/*** 查询当前个人待执行的任务*/
@Test
public void findPendingTaskList() {//任务负责人String assignee = "zhangsan";List<Task> list = taskService.createTaskQuery().processDefinitionKey("qingjia") //流程Key.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());}
}@Autowired
private HistoryService historyService;/*** 查询已处理历史任务*/
@Test
public void findProcessedTaskList() {//张三已处理过的历史任务List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processDefinitionKey("qingjia") //流程Key.taskAssignee("zhangsan").finished().list();for (HistoricTaskInstance historicTaskInstance : list) {System.out.println("流程实例id:" + historicTaskInstance.getProcessInstanceId());System.out.println("任务id:" + historicTaskInstance.getId());System.out.println("任务负责人:" + historicTaskInstance.getAssignee());System.out.println("任务名称:" + historicTaskInstance.getName());}
}

说明:

  • 流程实例id:一个流程只有一个,标识这个流程
  • 任务id:流程每进行到某个节点,就会给这个节点分配一个任务id

1.4.4 处理当前任务

任务负责人查询待办任务,选择任务进行处理,完成任务。

@Test
public void completTask(){Task task = taskService.createTaskQuery().processDefinitionKey("qingjia") //流程Key.taskAssignee("zhangsan")  //要查询的负责人.singleResult();//返回一条//完成任务,参数:任务idtaskService.complete(task.getId());
}

完成任务后,任务自动到下一个节点

1.4.5 流程定义

/*** 查询流程定义*/
@Test
public void findProcessDefinitionList(){List<ProcessDefinition> definitionList = repositoryService.createProcessDefinitionQuery().processDefinitionKey("qingjia").orderByProcessDefinitionVersion().desc().list();//输出流程定义信息for (ProcessDefinition processDefinition : definitionList) {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());}
}/*** 删除流程定义*/
public void deleteDeployment() {//部署idString deploymentId = "82e3bc6b-81da-11ed-8e03-7c57581a7819";//删除流程定义,如果该流程定义已有流程实例启动则删除时出错repositoryService.deleteDeployment(deploymentId);//设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式//repositoryService.deleteDeployment(deploymentId, true);
}

1.5 新版校验操作

1.5.1 配置Security用户

@Configuration
@EnableWebSecurity
public class MyWebSecurityConfiguration {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeRequests(authorize -> authorize.anyRequest().authenticated()).formLogin(Customizer.withDefaults());return http.build();}@Beanpublic WebSecurityCustomizer webSecurityCustomizer() {return (web) -> web.ignoring().requestMatchers()// Spring Security should completely ignore URLs starting with /resources/.antMatchers("/**");}@Beanpublic UserDetailsService userDetailsService() {UserDetails admin = User.withUsername("tom").password("$2a$10$tk29HhXGXCZDOSvn.VZlFeBsLmtJrKE2Uv6zLrRpTyvZMu3ipQLgC").roles("ACTIVITI_USER", "ACTIVITI_ADMIN", "APPLICATION_MANAGER").build();UserDetails user = User.withUsername("jerry").password("$2a$10$tk29HhXGXCZDOSvn.VZlFeBsLmtJrKE2Uv6zLrRpTyvZMu3ipQLgC").roles("ACTIVITI_USER", "GROUP_BUSINESS_MANAGER").build();UserDetails zhangsan = User.withUsername("zhangsan").password("$2a$10$tk29HhXGXCZDOSvn.VZlFeBsLmtJrKE2Uv6zLrRpTyvZMu3ipQLgC").roles("ACTIVITI_USER").build();UserDetails lisi = User.withUsername("lisi").password("$2a$10$tk29HhXGXCZDOSvn.VZlFeBsLmtJrKE2Uv6zLrRpTyvZMu3ipQLgC").roles("ACTIVITI_USER").build();return new InMemoryUserDetailsManager(admin, user, zhangsan, lisi);}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}public static void main(String[] args) {System.out.println(new BCryptPasswordEncoder().encode("123456"));}
}

Security工具类

@Component
public class SecurityUtil {@Autowiredprivate UserDetailsService userDetailsService;public void logInAs(String username) {UserDetails user = userDetailsService.loadUserByUsername(username);if (null == user) {throw new IllegalStateException(String.format("用户【%s】不存在", username));}SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return user.getAuthorities();}@Overridepublic Object getCredentials() {return user.getPassword();}@Overridepublic Object getDetails() {return user;}@Overridepublic Object getPrincipal() {return user;}@Overridepublic boolean isAuthenticated() {return true;}@Overridepublic void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {}@Overridepublic String getName() {return user.getUsername();}}));org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);}
}

1.5.2 操作

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestSecurityActiviti {@Autowiredprivate ProcessRuntime processRuntime;@Autowiredprivate TaskRuntime taskRuntime;@Autowiredprivate SecurityUtil securityUtil;@Testpublic void findProcess(){securityUtil.logInAs("jack");final ProcessDefinition processDefinition = processRuntime.processDefinition("apply");log.info("流程定义内容:{}",processDefinition);final Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));for (ProcessDefinition definition : processDefinitionPage.getContent()) {log.info("2- 流程定义内容:  {}",definition);}}/*** 启动流程*/@Testpublic void startProcess(){
//        设置登录用户securityUtil.logInAs("system");ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder.start().withProcessDefinitionKey("apply").build());log.info("流程实例的内容,{}",processInstance);}/*** 执行任务*/@Testpublic void doTask(){
//        设置登录用户securityUtil.logInAs("jerry");
//        查询任务Page<Task> taskPage = taskRuntime.tasks(Pageable.of(0, 10));if(taskPage != null && taskPage.getTotalItems()>0){for (Task task : taskPage.getContent()) {//        拾取任务taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());log.info("任务内容,{}",task);//        完成任务taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());}}}
}

1.5.3 报错 Process definition with the given id:xxx belongs to a different application version

报错参考:https://blog.csdn.net/u011410254/article/details/117368489
在resources目录下添加文件default-project.json内容:

{"createdBy": "superadminuser","creationDate": "2019-08-16T15:58:46.056+0000","lastModifiedBy": "qa-modeler-1","lastModifiedDate": "2019-08-16T16:03:41.941+0000","id": "c519a458-539f-4385-a937-2edfb4045eb9","name": "projectA","description": "","version": "1"
}

application配置文件:


# project manifest path
project.manifest.file.path=classpath:/default-project.json

1.6 Activiti 7.1.0.M6之后

activiti-spring-boot-starter最大是支持到7.1.0.M6,在大版本就需要 如下处理
pom.xml

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.5</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.activiti</groupId><artifactId>activiti-dependencies</artifactId><version>7.6.1</version><scope>import</scope><type>pom</type></dependency></dependencies></dependencyManagement><repositories><repository><id>activiti-releases</id><url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases</url></repository></repositories>

修改 mirror 镜像

  <mirrors><mirror><id>nexus-aliyun</id><mirrorOf>*,!activiti-releases</mirrorOf><url>https://maven.aliyun.com/repository/public</url>	</mirror></mirrors>

这篇关于工作流之Activiti7 和BPMN讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

工作常用指令与快捷键

Git提交代码 git fetch  git add .  git commit -m “desc”  git pull  git push Git查看当前分支 git symbolic-ref --short -q HEAD Git创建新的分支并切换 git checkout -b XXXXXXXXXXXXXX git push origin XXXXXXXXXXXXXX

嵌入式方向的毕业生,找工作很迷茫

一个应届硕士生的问题: 虽然我明白想成为技术大牛需要日积月累的磨练,但我总感觉自己学习方法或者哪些方面有问题,时间一天天过去,自己也每天不停学习,但总感觉自己没有想象中那样进步,总感觉找不到一个很清晰的学习规划……眼看 9 月份就要参加秋招了,我想毕业了去大城市磨练几年,涨涨见识,拓开眼界多学点东西。但是感觉自己的实力还是很不够,内心慌得不行,总怕浪费了这人生唯一的校招机会,当然我也明白,毕业

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所

未来工作趋势:零工小程序在共享经济中的作用

经济在不断发展的同时,科技也在飞速发展。零工经济作为一种新兴的工作模式,正在全球范围内迅速崛起。特别是在中国,随着数字经济的蓬勃发展和共享经济模式的深入推广,零工小程序在促进就业、提升资源利用效率方面显示出了巨大的潜力和价值。 一、零工经济的定义及现状 零工经济是指通过临时性、自由职业或项目制的工作形式,利用互联网平台快速匹配供需双方的新型经济模式。这种模式打破了传统全职工作的界限,为劳动

Smarty模板引擎工作机制(一)

深入浅出Smarty模板引擎工作机制,我们将对比使用smarty模板引擎和没使用smarty模板引擎的两种开发方式的区别,并动手开发一个自己的模板引擎,以便加深对smarty模板引擎工作机制的理解。 在没有使用Smarty模板引擎的情况下,我们都是将PHP程序和网页模板合在一起编辑的,好比下面的源代码: <?php$title="深处浅出之Smarty模板引擎工作机制";$content=

ispunct函数讲解 <ctype.h>头文件函数

目录 1.头文件函数 2.ispunct函数使用  小心!VS2022不可直接接触,否则..!没有这个必要,方源一把抓住VS2022,顷刻 炼化! 1.头文件函数 以上函数都需要包括头文件<ctype.h> ,其中包括 ispunct 函数 #include<ctype.h> 2.ispunct函数使用 简述: ispunct函数一种判断字符是否为标点符号的函

3.比 HTTP 更安全的 HTTPS(工作原理理解、非对称加密理解、证书理解)

所谓的协议 协议只是一种规则,你不按规则来就无法和目标方进行你的工作 协议说白了只是人定的规则,任何人都可以定协议 我们不需要太了解细节,这些制定和完善协议的人去做的,我们只需要知道协议的一个大概 HTTPS 协议 1、概述 HTTPS(Hypertext Transfer Protocol Secure)是一种安全的超文本传输协议,主要用于在客户端和服务器之间安全地传输数据

深度学习速通系列:深度学习算法讲解

深度学习算法是一系列基于人工神经网络的算法,它们通过模拟人脑处理信息的方式来学习和解决复杂问题。这些算法在图像识别、语音识别、自然语言处理、游戏等领域取得了显著的成就。以下是一些流行的深度学习算法及其基本原理: 1. 前馈神经网络(Feedforward Neural Networks, FNN) 原理:FNN 是最基本的神经网络结构,它由输入层、隐藏层和输出层组成。信息从输入层流向隐藏层,最

C#设计模式(1)——单例模式(讲解非常清楚)

一、引言 最近在学设计模式的一些内容,主要的参考书籍是《Head First 设计模式》,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了帮助我更深入地理解设计模式,二同时可以给一些初学设计模式的朋友一些参考。首先我介绍的是设计模式中比较简单的一个模式——单例模式(因为这里只牵涉到一个类) 二、单例模式的介绍 说到单例模式,大家第一