依赖添加
要实现groovy解析,必须添加groovy相关依赖:
完整依赖如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>camunda-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>camunda-demo</name>
<description>camunda-demo</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter</artifactId>
<version>7.19.0</version>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
<version>7.19.0</version>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
<version>7.19.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.21</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在流程设计器Camunda Moderler中直接在节点的执行监听器中添加Groovy脚本
首先设计一个简单的会签流程:通过groovy给会签节点的集合变量指定办理人
会签节点会签属性设置如下:
接下来要做的事情就是在流程设计器上给assigneeList赋值一个Java中List类型的变量值了,我们直接在发起节点上通过在执行监听器中为assigneeList变量赋值,脚本如下:
execution.setVariable("assigneeList", ['admin', '123456']);
groovy脚本能直接获取execution上下文完成变量赋值。
完整的BPMN内容如下,可直接复制到Camunda Modeler中:
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1cmnlva" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.28.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.22.0">
<bpmn:process id="Process_0g9nn47" isExecutable="true" camunda:candidateStarterGroups="camunda-admin">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_1te69hv</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_1te69hv" sourceRef="StartEvent_1" targetRef="Activity_0qfvvrh" />
<bpmn:sequenceFlow id="Flow_1tmzlud" sourceRef="Activity_0qfvvrh" targetRef="Activity_1co84us" />
<bpmn:sequenceFlow id="Flow_19hh2z3" sourceRef="Activity_1co84us" targetRef="Activity_0hrricq" />
<bpmn:endEvent id="Event_1cx2pfq">
<bpmn:incoming>Flow_0np779x</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0np779x" sourceRef="Activity_0hrricq" targetRef="Event_1cx2pfq" />
<bpmn:userTask id="Activity_0qfvvrh" name="发起" camunda:assignee="admin">
<bpmn:extensionElements>
<camunda:executionListener event="start">
<camunda:script scriptFormat="groovy">execution.setVariable("assigneeList", ['admin', '123456']);</camunda:script>
</camunda:executionListener>
</bpmn:extensionElements>
<bpmn:incoming>Flow_1te69hv</bpmn:incoming>
<bpmn:outgoing>Flow_1tmzlud</bpmn:outgoing>
</bpmn:userTask>
<bpmn:userTask id="Activity_1co84us" name="会签" camunda:assignee="${assignee}">
<bpmn:incoming>Flow_1tmzlud</bpmn:incoming>
<bpmn:outgoing>Flow_19hh2z3</bpmn:outgoing>
<bpmn:multiInstanceLoopCharacteristics camunda:collection="assigneeList" camunda:elementVariable="assignee">
<bpmn:loopCardinality xsi:type="bpmn:tFormalExpression">2</bpmn:loopCardinality>
<bpmn:completionCondition xsi:type="bpmn:tFormalExpression">${nrOfInstances == nrOfCompletedInstances}</bpmn:completionCondition>
</bpmn:multiInstanceLoopCharacteristics>
</bpmn:userTask>
<bpmn:userTask id="Activity_0hrricq" name="确认" camunda:assignee="admin">
<bpmn:incoming>Flow_19hh2z3</bpmn:incoming>
<bpmn:outgoing>Flow_0np779x</bpmn:outgoing>
</bpmn:userTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0g9nn47">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1cx2pfq_di" bpmnElement="Event_1cx2pfq">
<dc:Bounds x="752" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_10ufio1_di" bpmnElement="Activity_0qfvvrh">
<dc:Bounds x="270" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0qlom17_di" bpmnElement="Activity_1co84us">
<dc:Bounds x="430" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0bedgbv_di" bpmnElement="Activity_0hrricq">
<dc:Bounds x="590" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1te69hv_di" bpmnElement="Flow_1te69hv">
<di:waypoint x="215" y="117" />
<di:waypoint x="270" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1tmzlud_di" bpmnElement="Flow_1tmzlud">
<di:waypoint x="370" y="117" />
<di:waypoint x="430" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_19hh2z3_di" bpmnElement="Flow_19hh2z3">
<di:waypoint x="530" y="117" />
<di:waypoint x="590" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0np779x_di" bpmnElement="Flow_0np779x">
<di:waypoint x="690" y="117" />
<di:waypoint x="752" y="117" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
Groovy脚本在流程引擎中能提供的能力
由于groovy脚本能直接在流程设计器中编码不需要经过代码编译打包再重启流程引擎,能极大地提高流程引擎的灵活性,主要表现在以下方面:
1. 条件表达式与决策逻辑
- 条件流转:在流程的条件网关或任务监听器中,Groovy 脚本可以用来编写复杂的条件表达式,决定任务是否继续流转。例如,在流程中的排他网关(Exclusive Gateway)里,可以根据某个条件来判断分支。
- 决策表:通过 Groovy 脚本可以动态地执行决策逻辑,替代硬编码的分支判断,从而使流程更加灵活,且易于后期维护。
2. 数据操作与传递
- 变量赋值:Groovy 脚本可以用来处理和操作流程变量,修改现有变量的值,或者根据外部输入计算值并返回。
- 变量传递:在不同的任务之间,Groovy 脚本可以帮助处理变量的传递,确保数据在整个流程生命周期中能够正确流动。
3. 自定义任务处理
- 自定义服务任务:可以通过 Groovy 脚本在服务任务(Service Task)中实现自定义的业务逻辑,如调用外部系统接口、进行复杂的数据处理等。
- 异步任务:Groovy 脚本可以帮助处理异步任务的执行,确保任务按需执行并返回结果。
4. 流程控制
- 循环和迭代:Groovy 脚本可以在任务中实现循环或迭代操作,处理集合数据类型,并基于数据变化调整流程的执行路径。
- 动态任务创建:通过 Groovy 脚本可以动态地生成任务或子流程,并将任务与特定的流程路径进行绑定。
5. 任务监听与事件驱动
- 任务事件监听器:Groovy 脚本常用于定义任务创建、任务完成、任务删除等事件的监听器,帮助实现基于事件驱动的业务逻辑,如任务状态变更时触发通知、审计等操作。
- 流程事件监听器:在流程级别,通过 Groovy 脚本可以监听流程的启动、结束等事件,进行相关的业务处理或记录日志。
6. 集成外部系统
- 调用外部接口:Groovy 脚本可以直接通过 HTTP、SOAP、REST 等协议,调用外部的 Web 服务接口,处理外部数据交互。
- 数据库操作:Groovy 允许在流程中进行数据库操作,直接访问和修改数据库中的数据,适用于需要频繁读取或写入数据的场景。
7. 性能优化
- 动态配置:Groovy 脚本可以根据不同的执行环境或者用户输入,动态调整流程的执行参数,优化流程的性能。
- 并行处理:通过 Groovy 脚本可以控制流程的并行任务执行,优化工作流的处理速度和效率。
8. 简化流程设计
- 脚本任务简化:通过在流程中使用 Groovy 脚本,开发者可以避免冗长和复杂的流程设计,简化流程图,降低流程管理的复杂度。
- 增强表达能力:Groovy 语法简单且强大,能够处理复杂的条件、数据类型、正则表达式等,增强了流程的表达能力。