Springboot自动部署Activiti7

自动部署

其实SpringBoot集成Activiti7之后,支持了自动部署的功能,接下来我们也来一起学习一下。

准备流程图

首选我们来准一个要自动部署的流程图文件,这里可以直接使用前面我们画好的流程图,改造一下即可。

  • 复制bpmn-01.xml,并修改名称为auto-deployment.bpmn20.xml,文件名必须以.bpmn20.xml结尾,SpringBoot才认识
  • 在auto-deployment.bpmn20.xml中修改process的id属性值,以避免后续部署时流程定义重复

image-20230820133700569

拷贝到自动部署目录

把准备好的auto-deployment.bpmn20.xml文件拷贝到项目resources/processes目录下,没有自己可以创建一下。

image-20230820134058100

启动自动部署

接下来直接启动类,启动完成后,我们可以在控制台看见下面日志,即可说明程序部署成功了。

image-20230820134411705

同时也可以在act_re_deployment表中看见相关信息:

image-20240802173330481

如果我们不删除xml文件,再次重启启动类,可以在控制台看见一下信息,则说明SpringBoot自动部署会检查流程图xml是否有变更,如果没有则跳过,有则会重新部署

image-20230820134730783

五种自动部署模式

SpringBoot在自动部署上,给我们提供了5种模式,可以在yml文件中通过deployment-mode属性设置,如果你不用自动部署功能,则推荐值为never-fail。

1
2
3
4
5
6
7
8
9
spring:
application:
name: demo-activiti
activiti:
database-schema-update: true #自动创建数据库
deployment-mode: never-fail # 流程自动部署,所有资源一次性部署,只部署验证成功的流程,如果没有要部署的流程不抛错
check-process-definitions: false # 关闭流程xml校验
db-history-used: true # 开启流程历史记录
history-level: full # 历史流程数据全部记录到历史表中,支持none、activity、audit、full,4种粒度的数据,常用的就是full

其它值:

  • default # 自动部署,所有资源一次性部署(既一次部署,包括多个流程图xml资源),不管有没有部署资源都会部署一次
  • never-fail # 自动部署,所有资源一次性部署,只部署验证成功的流程,如果没有要部署的流程不抛错
  • fail-on-no-process # 自动部署,所有资源一次性部署,只部署验证成功的流程,如果没有要部署的流程则抛错
  • resource-parent-folder # 自动部署,按照文件夹自动分组部署,一个文件夹一次部署
  • single-resource # 自动部署,一个资源文件就创建一次部署

new API介绍

上述同意和不同意,其实在Activiti7中还提供了另外的API可以来实现,这些API被称为new API(之前自然也就称为old API),比如同意的功能实现可以用new API写成如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Autowired
TaskRuntime taskRuntime;

/**
* 同意
*/
@ParameterizedTest
@ValueSource(strings = {"34501ba0-3f2c-11ee-b9d9-4c1d965eab77"})
public void testAgree(String taskId){
// 把【同意】看做是填写的【审批表单(包括:审批结果、审批意见)】中的approvalStatus字段
Map<String, Object> variables = new HashMap<>();
variables.put("approvalStatus","同意");
variables.put("approvalNote","");
// 标记任务完成
// taskService.complete(taskId, variables);

// new API:
taskRuntime.complete(TaskPayloadBuilder.complete()
.withTaskId(taskId)
.withVariables(variables)
.build()
);
}

虽然new API提供更优雅的构建器+链式编程的方式,但是上述代码运行时会抛出以下错误:

image-20230820154038655

这是因为所有new API都会从SpringSecurity中去获取当前登录用户、分组等信息,再通过这些信息再去校验是否有对流程的任务的操作权限,因此会抛出上述类似的错误。

而我们在之前SpringBoot集成Activiti7的过程中,是直接把SpringSecurity的配置写死了,因此上面代码运行的时候获取的用户是写死的默认值’miukoo-user-1’,与我们当前【经理审批】人李四,不匹配,因此出现了此错误。

明白了原理,那么你想让上述代码正常执行,则需要改动一下写死的SpringSecurity配置中的用户,然后执行即可成功。

image-20230820154707500

对于old和new API,你会发现old API直接调用,没有任何限制,而new API从SpringSecurity中拿到的用户信息与当前流程待办人信息一致才可以调用成功。显然new API对于程序的耦合性更高,这也是Activiti7设计不优雅的地方!因此在工作中推荐大家使用old API。