activiti流程引擎部署方式之BpmnModel以及使用
一、模型架构概览
在流程资源文件中,每一个节点元素在activiti中都有对应的元素属性承载类,比如,UserTask任务节点,它的元素属性承载类为UserTask,相同,startEvent开始节点的元素承载类为StartEvent,在bpmn流程文件进行解析时,也是将xml文档中每个元素解析为对应的承载类,从而进行组装成一个BmpnModel模型,我们可以直接由activiti将bpmn xml文件解析为一个实例模型(下图所示),也可以完成通过自定义手动创建模型。
BpmnModel.png二、BpmnModel模型部署实战
2.1、自定义BpmnModel模型实战
2.1.1、业务流程图
业务流程图.png2.1.2、流程文档xml描述
<process id="myProcess" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<userTask id="usertask1" name="提交审批"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow>
<userTask id="usertask2" name="总经理审批"></userTask>
<sequenceFlow id="flow3" name="大于三天" sourceRef="exclusivegateway1" targetRef="usertask2">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${day>3}]]></conditionExpression>
</sequenceFlow>
<userTask id="usertask3" name="部门经理审批"></userTask>
<sequenceFlow id="flow4" name="小于三天" sourceRef="exclusivegateway1" targetRef="usertask3">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${day<=3}]]></conditionExpression>
</sequenceFlow>
<endEvent id="endevent2" name="End"></endEvent>
<sequenceFlow id="flow6" sourceRef="usertask2" targetRef="endevent2"></sequenceFlow>
<sequenceFlow id="flow7" sourceRef="usertask3" targetRef="endevent2"></sequenceFlow>
</process>
2.1.3、自定义BpmnModel
@Test
public void genarateBpmnModel(){
//创建BpmnModel对象
BpmnModel bpmnModel = new BpmnModel();
/**
* 创建process节点 并添加至process
* <process id="myProcess" name="My process" isExecutable="true">
*/
Process process = new Process();
//executabl内置默认为true
process.setId("myProcess");
process.setName("My process");
/**
* 创建开始结束节点 并添加至process
* <startEvent id="startevent1" name="Start"></startEvent>
* <endEvent id="endevent2" name="End"></endEvent>
*/
StartEvent startEvent = new StartEvent();
startEvent.setId("startevent1");
startEvent.setName("Start");
EndEvent endEvent = new EndEvent();
endEvent.setId("endevent2");
endEvent.setName("End");
process.addFlowElement(startEvent);
process.addFlowElement(endEvent);
/**
* 创建任务节点 并添加至process
* <userTask id="usertask1" name="提交审批"></userTask>
*/
UserTask userTask1 = genarateUserTask("usertask1","提交审批");
UserTask userTask2 = genarateUserTask("usertask2","总经理审批");
UserTask userTask3 = genarateUserTask("usertask3","部门经理审批");
process.addFlowElement(userTask1);
process.addFlowElement(userTask2);
process.addFlowElement(userTask3);
/**
* 创建排他网关 并添加至process
* <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
*/
ExclusiveGateway exclusiveGateway = genarateExclusiveGateway("exclusivegateway1","Exclusive Gateway");
process.addFlowElement(exclusiveGateway);
/**
* 创建连线 并添加至process
* <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
*/
SequenceFlow sequenceFlow1 = genarateSequenceFlow("flow1","","startevent1","usertask1","",process);
process.addFlowElement(sequenceFlow1);
/**
* 创建连线 并添加至process
* <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow>
*/
SequenceFlow sequenceFlow2 = genarateSequenceFlow("flow2","","usertask1","exclusivegateway1","",process);
process.addFlowElement(sequenceFlow2);
/**
* 创建连线 并添加至process
* <sequenceFlow id="flow3" name="大于三天" sourceRef="exclusivegateway1" targetRef="usertask2">
* <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day>3}]]></conditionExpression>
* </sequenceFlow>
*/
SequenceFlow sequenceFlow3 = genarateSequenceFlow("flow3","大于三天","exclusivegateway1","usertask2","${day>3}",process);
process.addFlowElement(sequenceFlow3);
/**
* 创建连线 并添加至process
* <sequenceFlow id="flow4" name="小于三天" sourceRef="exclusivegateway1" targetRef="usertask3">
* <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day<=3}]]></conditionExpression>
* </sequenceFlow>
*/
SequenceFlow sequenceFlow4 = genarateSequenceFlow("flow4","小于三天","exclusivegateway1","usertask3","${day<=3}",process);
process.addFlowElement(sequenceFlow4);
/**
* 创建连线 并添加至process
* <sequenceFlow id="flow6" sourceRef="usertask2" targetRef="endevent2"></sequenceFlow>
* <sequenceFlow id="flow7" sourceRef="usertask3" targetRef="endevent2"></sequenceFlow>
*/
SequenceFlow sequenceFlow6 = genarateSequenceFlow("flow6","","usertask2","endevent2","",process);
SequenceFlow sequenceFlow7 = genarateSequenceFlow("flow7","","usertask3","endevent2","",process);
process.addFlowElement(sequenceFlow6);
process.addFlowElement(sequenceFlow7);
/**
* 为排他网关添加出线
*/
List<SequenceFlow> outgoingFlows = new ArrayList<>();
outgoingFlows.add(sequenceFlow3);
outgoingFlows.add(sequenceFlow4);
exclusiveGateway.setOutgoingFlows(outgoingFlows);
/**
* 将process封装至模型对象
*/
bpmnModel.addProcess(process);
}
/**
* 创建连线
*/
private SequenceFlow genarateSequenceFlow(String id, String name,String sourceRef, String tartgetRef, String conditionExpression, Process process) {
SequenceFlow sequenceFlow = new SequenceFlow(sourceRef,tartgetRef);
sequenceFlow.setId(id);
if(name != null && name != ""){
sequenceFlow.setName(name);
}
sequenceFlow.setSourceFlowElement(process.getFlowElement(sourceRef));
sequenceFlow.setTargetFlowElement(process.getFlowElement(tartgetRef));
if(conditionExpression !=null && conditionExpression != ""){
sequenceFlow.setConditionExpression(conditionExpression);
}
return sequenceFlow;
}
/**
* 创建排他网关
*/
private ExclusiveGateway genarateExclusiveGateway(String id, String name) {
ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
exclusiveGateway.setId(id);
exclusiveGateway.setName(name);
return exclusiveGateway;
}
/**
* 创建用户人物节点
*/
private UserTask genarateUserTask(String id, String name) {
UserTask userTask = new UserTask();
userTask.setId(id);
userTask.setName(name);
return userTask;
}
2.1.4、模型正确性校验
关于模型校验器更多细节可查看activiti源码剖析之BpmnModel模型校验器
ProcessValidatorFactory processValidatorFactory = new ProcessValidatorFactory();
ProcessValidator processValidator = processValidatorFactory.createDefaultProcessValidator();
List<ValidationError> validate = processValidator.validate(bpmnModel);
if(validate.size()>=1){
for (ValidationError validationError : validate) {
System.out.println(validationError.getProblem());
System.out.println(validationError.isWarning());
}
}
2.2、BpmnModel模型部署实战
Deployment deploy = deploymentBuilder.addBpmnModel("test.bpmn", bpmnModel).deploy();
三、Bpmn模型相关使用实战
- XML流程文档转化为BpmnModel
//获取部署资源输入流
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("process/delegateTest.bpmn");
//deploymentBuilder.addInputStream("delegateTest.bpmn",inputStream).deploy();
//创建转换器
BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
InputStreamProvider inputStreamProvider = new InputStreamSource(inputStream);
BpmnModel bpmnModel = bpmnXMLConverter.convertToBpmnModel(inputStreamProvider, true, false, "UTF-8");
- BpmnModel转化为XML文档
byte[] bytes = bpmnXMLConverter.convertToXML(bpmnModel);
System.out.println(new String(bytes));
- 数据库中存在的流程文档转化为模型
String processDefinitionId = "delegateTest:1:4";
BpmnModel bpmnModel = processEngine.getRepositoryService().getBpmnModel(processDefinitionId);
- 获取流程文档坐标布局信息
String processDefinitionId = "delegateTest:1:4";
DiagramLayout processDiagramLayout = processEngine.getRepositoryService().getProcessDiagramLayout(processDefinitionId);
Map<String, DiagramElement> elements = processDiagramLayout.getElements();
Set<Map.Entry<String, DiagramElement>> entries = elements.entrySet();
for (Map.Entry<String,DiagramElement> entry : entries){
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
- 获取流程节点信息
String processDefinitionId = "delegateTest:1:4";
//获取模型
BpmnModel bpmnModel = processEngine.getRepositoryService().getBpmnModel(processDefinitionId);
//获取流程Process
Process process = bpmnModel.getProcesses().get(0);
//获取指定类型节点
List<UserTask> flowElementsOfType = process.findFlowElementsOfType(UserTask.class);
for (UserTask userTask : flowElementsOfType) {
System.out.println(userTask.getId());
}
网友评论