工作流基础:Camunda 官方快速入门教程中文版 工作流进阶(java):Camunda SpringBoot与进阶内容
新版本camunda-modeler的UI改了不少,对应起来比较麻烦,固博客记录一次实际使用过程。
启动类添加新注解
@EnableProcessApplication
依赖
<!--camunda-->
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter</artifactId>
<version>7.16.0</version>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
<version>7.16.0</version>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
<version>7.16.0</version>
</dependency>
<!--camunda外部任务-->
<dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-external-task-client</artifactId>
<version>7.16.0</version>
</dependency>
yml
camunda.bpm:
# 配置账户密码来访问Camunda自带的管理界面
admin-user:
id: demo
password: demo
firstName: Demo
filter:
create: All tasks
在META-INF中创建processes.xml文件,不用填啥,作用可见processes.xml文件介绍
配置后第一次启动项目非常慢,启动成功后数据库会多出49张表
进入localhost:端口/camunda/app/cockpit/default/#/login可见camunda首页,yml中配置为demo
(若修改用户id会新创建一个用户原用户不会删除)
登录进入控制台
控制台汉化:汉化链接
汉化效果:(驾驶舱内部未汉化,其他两个内部汉化了)
camunda-modeler(绘制流程工具)
1.下载路径 2.找个路径解压放好
3.IDEA安装外部Tools(选择解压路径的Camunda Modeler.exe)
4.使用时右击项目名
常用流程元素绘制方法与作用
1.服务任务(可绑定一个java类进行一些业务的处理,可以对一些流程所用参数进行赋值获取)例如本任务绑定了ceshi.camunda包下的AmountObtained类
2.用户任务(一般用于处理一些表单,例如在这里我给他创建了一个表单,当流程执行到这一步时,他需要对表单内的三个流程参数(amount,item,approved)进行处理
表单效果(参数类型决定交互形式)
3.排他网关(此处将会出现分支)
虽然排他网关直接创建就行,但网关后边的线需要添加一些设置,见下图,意为当表达式!approved为真时走这条线。
使用流程
1.使用camunda-modeler绘制流程图
2.点击流程图空白处设置流程id
3.启动后台(可进入localhost:端口/camunda/app/cockpit/default/#/login)的情况下,如下图进行部署至http://localhost:端口号/engine-rest。
上述流程图xml
<?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:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1gjpsmr" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.11.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.18.0">
<bpmn:process id="lc_1" name="测试流程" isExecutable="true" camunda:versionTag="1">
<bpmn:startEvent id="StartEvent_1" name="付款请求">
<bpmn:extensionElements />
<bpmn:outgoing>Flow_03ld858</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:serviceTask id="lc1" name="付款" camunda:class="ceshi.camunda.Pay">
<bpmn:extensionElements />
<bpmn:incoming>Flow_1wbv7x2</bpmn:incoming>
<bpmn:incoming>Flow_0ios1ht</bpmn:incoming>
<bpmn:outgoing>Flow_0uifauc</bpmn:outgoing>
</bpmn:serviceTask>
<bpmn:endEvent id="Event_1uiw1w2" name="付款成功">
<bpmn:incoming>Flow_0uifauc</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0uifauc" sourceRef="lc1" targetRef="Event_1uiw1w2">
<bpmn:extensionElements />
</bpmn:sequenceFlow>
<bpmn:userTask id="Activity_0ftu49q" name="批准付款">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="amount" label="金额" type="long">
<camunda:properties />
<camunda:validation />
</camunda:formField>
<camunda:formField id="item" label="项目" type="string" />
<camunda:formField id="approved" label="是否同意?" type="boolean" defaultValue="0" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>Flow_13bfg5g</bpmn:incoming>
<bpmn:outgoing>Flow_0qaxuvo</bpmn:outgoing>
</bpmn:userTask>
<bpmn:exclusiveGateway id="Gateway_1j1iu5v" name="金额判断">
<bpmn:extensionElements />
<bpmn:incoming>Flow_1296l8i</bpmn:incoming>
<bpmn:outgoing>Flow_13bfg5g</bpmn:outgoing>
<bpmn:outgoing>Flow_1wbv7x2</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:exclusiveGateway id="Gateway_0vjm41f" name="是否付款">
<bpmn:incoming>Flow_0qaxuvo</bpmn:incoming>
<bpmn:outgoing>Flow_0n3lkgl</bpmn:outgoing>
<bpmn:outgoing>Flow_0ios1ht</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:endEvent id="Event_1if8jwl" name="付款失败">
<bpmn:incoming>Flow_0n3lkgl</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_13bfg5g" name="金额>=500" sourceRef="Gateway_1j1iu5v" targetRef="Activity_0ftu49q">
<bpmn:extensionElements />
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${amount1>=500}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="Flow_0qaxuvo" sourceRef="Activity_0ftu49q" targetRef="Gateway_0vjm41f" />
<bpmn:sequenceFlow id="Flow_0n3lkgl" name="不付款" sourceRef="Gateway_0vjm41f" targetRef="Event_1if8jwl">
<bpmn:extensionElements />
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${!approved}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="Flow_1wbv7x2" name="金额小于500" sourceRef="Gateway_1j1iu5v" targetRef="lc1">
<bpmn:extensionElements />
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${amount1<500}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="Flow_0ios1ht" name="付款" sourceRef="Gateway_0vjm41f" targetRef="lc1">
<bpmn:extensionElements />
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${approved}</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="Flow_03ld858" sourceRef="StartEvent_1" targetRef="Activity_0vigtys" />
<bpmn:sequenceFlow id="Flow_1296l8i" sourceRef="Activity_0vigtys" targetRef="Gateway_1j1iu5v" />
<bpmn:serviceTask id="Activity_0vigtys" name="需付金额" camunda:class="ceshi.camunda.AmountObtained">
<bpmn:extensionElements />
<bpmn:incoming>Flow_03ld858</bpmn:incoming>
<bpmn:outgoing>Flow_1296l8i</bpmn:outgoing>
</bpmn:serviceTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="lc_1">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="152" y="252" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="148" y="295" width="45" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1s1q5dy_di" bpmnElement="lc1">
<dc:Bounds x="513" y="230" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1uiw1w2_di" bpmnElement="Event_1uiw1w2">
<dc:Bounds x="685" y="252" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="682" y="295" width="44" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_18lqe2t_di" bpmnElement="Activity_0ftu49q">
<dc:Bounds x="343" y="90" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_1j1iu5v_di" bpmnElement="Gateway_1j1iu5v" isMarkerVisible="true">
<dc:Bounds x="368" y="245" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="371" y="305" width="45" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_0vjm41f_di" bpmnElement="Gateway_0vjm41f" isMarkerVisible="true">
<dc:Bounds x="538" y="105" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="540" y="81" width="45" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1if8jwl_di" bpmnElement="Event_1if8jwl">
<dc:Bounds x="685" y="112" width="36" height="36" />
<bpmndi:BPMNLabel>
<dc:Bounds x="681" y="155" width="45" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1pc41zh_di" bpmnElement="Activity_0vigtys">
<dc:Bounds x="230" y="230" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0uifauc_di" bpmnElement="Flow_0uifauc">
<di:waypoint x="613" y="270" />
<di:waypoint x="685" y="270" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_13bfg5g_di" bpmnElement="Flow_13bfg5g">
<di:waypoint x="393" y="245" />
<di:waypoint x="393" y="170" />
<bpmndi:BPMNLabel>
<dc:Bounds x="336" y="203" width="53" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0qaxuvo_di" bpmnElement="Flow_0qaxuvo">
<di:waypoint x="443" y="130" />
<di:waypoint x="538" y="130" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0n3lkgl_di" bpmnElement="Flow_0n3lkgl">
<di:waypoint x="588" y="130" />
<di:waypoint x="685" y="130" />
<bpmndi:BPMNLabel>
<dc:Bounds x="620" y="112" width="34" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1wbv7x2_di" bpmnElement="Flow_1wbv7x2">
<di:waypoint x="418" y="270" />
<di:waypoint x="513" y="270" />
<bpmndi:BPMNLabel>
<dc:Bounds x="432" y="252" width="62" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0ios1ht_di" bpmnElement="Flow_0ios1ht">
<di:waypoint x="563" y="155" />
<di:waypoint x="563" y="230" />
<bpmndi:BPMNLabel>
<dc:Bounds x="567" y="183" width="23" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_03ld858_di" bpmnElement="Flow_03ld858">
<di:waypoint x="188" y="270" />
<di:waypoint x="230" y="270" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1296l8i_di" bpmnElement="Flow_1296l8i">
<di:waypoint x="330" y="270" />
<di:waypoint x="368" y="270" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
java使用测试
流程图绑定的java类(实现JavaDelegate后重新execute方法):AmountObtained
package ceshi.camunda;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import java.util.logging.Logger;
public class AmountObtained implements JavaDelegate {
private final static Logger LOGGER = Logger.getLogger("OBTAINED-REQUESTS");
@Override
public void execute(DelegateExecution execution) {
execution.setVariable("amount1",999);//添加流程参数amount1值为999
LOGGER.info("amount1 " + execution.getVariable("amount1"));//打印流程参数amount1
}
}
流程图绑定的java类:Pay
package ceshi.camunda;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import java.util.logging.Logger;
public class Pay implements JavaDelegate {
private final static Logger LOGGER = Logger.getLogger("PAY-REQUESTS");
@Override
public void execute(DelegateExecution execution) {
LOGGER.info("付款金额:amount " + execution.getVariable("amount"));//打印用户表单输入的金额
LOGGER.info("付款项目:item " + execution.getVariable("item"));
LOGGER.info("---付款过程---");
LOGGER.info("最终付款结果:"+(boolean)execution.getVariable("approved"));
}
}
启动一个流程实例
@Autowired
private RuntimeService runtimeService;
runtimeService.startProcessInstanceByKey("lc_1");//lc_1为流程id
点击任务列表
发现流程直接进行到了批量付款
原因是我们在需付进行金额绑定的java类中设置的流程属性值为999,而我们判断的表达式时amount1>=500
回到控制台任务列表,点击表单输入值点击完成
发现打印了一下参数(触发了付款节点绑定的java类),至此一次完整流程走完
补充:
1.指定用户执行(直接给变量赋值即可指定用户)同步系统用户方法
2.节点监听(流程运行到这里触发方法)可选择进入节点执行或完成节点执行等
public class TaskListener implements ExecutionListener {
@Autowired
private static RepositoryService repositoryService;
@Override
public void notify(DelegateExecution execution) throws Exception {
//要执行的业务逻辑
}
}