注意:此处使用activiti6.0版本,使用自动布局和不使用自动布局,pom坐标有差异
如果是前后端分离的项目,我建议前端使用bpmn.js来生成bpmn文件,后端只负责部署流转即可,此处代码是采用activiti提供的后端生成bpmn的方式,此种方式不常用,但可以作为技术储备
采用activiti提供的自动布局
pom
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-spring-boot-starter-basicartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-json-converterartifactId>
<version>${activiti.version}version>
<exclusions>
<exclusion>
<groupId>org.activitigroupId>
<artifactId>activiti-bpmn-modelartifactId>
exclusion>
exclusions>
dependency
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-spring-boot-starter-basicartifactId>
<version>${activiti.version}version>
dependency>
java代码
实现TaskListener接口【需要根据业务进行重写】【监听器的添加与否需要根据业务进行来决定】
package com.adun.listener;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
public class MyTaskListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
System.out.println(delegateTask);
String eventName = delegateTask.getEventName();
switch (eventName) {
case EVENTNAME_CREATE:
//2
System.out.println("监听到任务创建");
break;
case EVENTNAME_ASSIGNMENT:
//1
System.out.println("监听到指定任务代理人");
break;
case EVENTNAME_COMPLETE:
//3
System.out.printf("监听到任务 %s 完成\n", delegateTask.getId());
break;
case EVENTNAME_DELETE:
//4
System.out.printf("监听到任务 %s 删除\n", delegateTask.getId());
break;
default:
break;
}
}
}
package com.adun;
import com.adun.listener.MyTaskListener;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.*;
import java.lang.reflect.Array;
import java.util.*;
/**
* @author ADUN
* @date 2021/11/4 17:39
*/
@SpringBootTest
public class BpmnCreateTest {
@Test
public void generateBpmn(){
//创建一个BPMN模型实例
BpmnModel bpmnModel = new BpmnModel();
//创建流程
Process process = new Process();
process.setId("myProcess");
bpmnModel.getProcesses().add(process);
//创建开始事件
StartEvent startEvent = new StartEvent();
startEvent.setId("startEvent");
process.addFlowElement(startEvent);
//设置开始事件的图形信息
GraphicInfo graphicInfo1 = new GraphicInfo();
graphicInfo1.setHeight(30);
graphicInfo1.setWidth(30);
graphicInfo1.setX(100);
graphicInfo1.setY(140);
bpmnModel.addGraphicInfo("startEvent",graphicInfo1);
//创建监听器
ActivitiListener activitiListener = new ActivitiListener();
activitiListener.setEvent(TaskListener.EVENTNAME_CREATE);
activitiListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
activitiListener.setImplementation(MyTaskListener.class.getTypeName());
List<ActivitiListener> activitiListeners = new ArrayList<>();
activitiListeners.add(activitiListener);
//创建任务
UserTask task = new UserTask();
task.setId("myTask");
task.setTaskListeners(activitiListeners);
process.addFlowElement(task);
//设置任务的图形信息
GraphicInfo graphicInfo = new GraphicInfo();
graphicInfo.setHeight(100);
graphicInfo.setWidth(200);
graphicInfo.setX(200);
graphicInfo.setY(120);
bpmnModel.addGraphicInfo("myTask",graphicInfo);
//创建结束事件
EndEvent endEvent = new EndEvent();
endEvent.setId("endEvent");
process.addFlowElement(endEvent);
//设置结束事件的图形信息
GraphicInfo graphicInfo2 = new GraphicInfo();
graphicInfo2.setHeight(30);
graphicInfo2.setWidth(30);
graphicInfo2.setX(500);
graphicInfo2.setY(140);
bpmnModel.addGraphicInfo("endEvent",graphicInfo2);
//将元素用线连起来
//创建线1
SequenceFlow sequenceFlow1 = new SequenceFlow();
sequenceFlow1.setId("mySequenceFlow1");
sequenceFlow1.setSourceRef(startEvent.getId());
sequenceFlow1.setTargetRef(task.getId());
process.addFlowElement(sequenceFlow1);
//设置线1的图形信息【可以不用设置,影响不大】
GraphicInfo graphicInfo3 = new GraphicInfo();
graphicInfo3.setX(135);
graphicInfo3.setY(169);
GraphicInfo graphicInfo4 = new GraphicInfo();
graphicInfo4.setX(200);
graphicInfo4.setY(170);
List<GraphicInfo> graphicInfos1 = new ArrayList<>();
graphicInfos1.add(graphicInfo3);
graphicInfos1.add(graphicInfo4);
bpmnModel.addFlowGraphicInfoList("mySequenceFlow1",graphicInfos1);
//创建线2
SequenceFlow sequenceFlow2 = new SequenceFlow();
sequenceFlow2.setId("mySequenceFlow2");
sequenceFlow2.setSourceRef(task.getId());
sequenceFlow2.setTargetRef(endEvent.getId());
process.addFlowElement(sequenceFlow2);
//设置线2的图形信息【可以不用设置,影响不大】
GraphicInfo graphicInfo5 = new GraphicInfo();
graphicInfo5.setX(400);
graphicInfo5.setY(170);
GraphicInfo graphicInfo6 = new GraphicInfo();
graphicInfo6.setX(500);
graphicInfo6.setY(169);
List<GraphicInfo> graphicInfos2 = new ArrayList<>();
graphicInfos2.add(graphicInfo5);
graphicInfos2.add(graphicInfo6);
bpmnModel.addFlowGraphicInfoList("mySequenceFlow2",graphicInfos2);
//XML转换器,将BPMN模型转换为XML文档
BpmnXMLConverter converter = new BpmnXMLConverter();
byte[] bytes = converter.convertToXML(bpmnModel);
System.out.println(new String(bytes));
}
}
<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/test">
<process id="myProcess" isExecutable="true">
<startEvent id="startEvent">startEvent>
<userTask id="myTask">
<extensionElements>
<activiti:taskListener event="create" class="com.adun.listener.MyTaskListener">activiti:taskListener>
extensionElements>
userTask>
<endEvent id="endEvent">endEvent>
<sequenceFlow id="mySequenceFlow1" sourceRef="startEvent" targetRef="myTask">sequenceFlow>
<sequenceFlow id="mySequenceFlow2" sourceRef="myTask" targetRef="endEvent">sequenceFlow>
process>
<bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
<bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
<bpmndi:BPMNShape bpmnElement="startEvent" id="BPMNShape_startEvent">
<omgdc:Bounds height="30.0" width="30.0" x="100.0" y="140.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="myTask" id="BPMNShape_myTask">
<omgdc:Bounds height="100.0" width="200.0" x="200.0" y="120.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endEvent" id="BPMNShape_endEvent">
<omgdc:Bounds height="30.0" width="30.0" x="500.0" y="140.0">omgdc:Bounds>
bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="mySequenceFlow1" id="BPMNEdge_mySequenceFlow1">
<omgdi:waypoint x="135.0" y="169.0">omgdi:waypoint>
<omgdi:waypoint x="200.0" y="170.0">omgdi:waypoint>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="mySequenceFlow2" id="BPMNEdge_mySequenceFlow2">
<omgdi:waypoint x="400.0" y="170.0">omgdi:waypoint>
<omgdi:waypoint x="500.0" y="169.0">omgdi:waypoint>
bpmndi:BPMNEdge>
bpmndi:BPMNPlane>
bpmndi:BPMNDiagram>
definitions>