activiti学习(二)——activiti流程的部署

进行了流程引擎的构建和初始化之后,接下来要做的就是把写好的流程文档部署到流程引擎中,后续activiti.cfg.xml的配置如果没有特指的话,一般就用第一章提供的例子。

首先画一个bpmn的图,可以通过集成开发环境的插件,也可以直接写xml形式。这里先写一个xml形式的bpmn图firstBPM.bpmn:

<?xml version="1.0" encoding="UTF-8"?>
<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="firstBpmProcess" name="My process" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="usertask1" name="myTask1" activiti:assignee="sadoshi"></userTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
    <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="41.0" width="35.0" x="505.0" y="40.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="470.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="505.0" y="240.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="522.0" y="81.0"></omgdi:waypoint>
        <omgdi:waypoint x="522.0" y="150.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="522.0" y="205.0"></omgdi:waypoint>
        <omgdi:waypoint x="522.0" y="240.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

大概是这样的一张流程图,一个开始节点,一个userTask节点,一个结束节点:

接着对这张流程图进行部署。部署的方法有文本方式、classpath方式、inputStream方式和zipInputStream方式。classpath的话要求bpmn文档在工程的classpath下,而其他几种方式则可以选择物理路径,比较灵活。另外zipInputStream适用于部署多张流程图打包而成的zip文件。这里展示使用inputStream方式的:

package engineDeploy;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.DeploymentBuilder;

public class App {

	private ProcessEngine pe;

	public void getFromProcessEngineConfiguration() {
		ProcessEngineConfiguration pec = ProcessEngineConfiguration
				.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
		pe = pec.buildProcessEngine();
	}
	
	public void deploy() {
		RepositoryService repositoryService = pe.getRepositoryService();
		DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
		
		InputStream inputStream = null;
		try {
			inputStream = App.class.getClassLoader().getResource("bpmn/firstBPM.bpmn").openStream();
			deploymentBuilder.addInputStream("first.bpmn", inputStream);
            deploymentBuilder.name("firstDeployment");
			deploymentBuilder.deploy();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		App app = new App();
		app.getFromProcessEngineConfiguration();
		app.deploy();
	}
}

注意,如果添加的资源是bpmn流程的话,第35行addInputStream的第一个参数,后缀名必须是bpmn或bpmn20.xml,否则流程引擎不会对其进行解析,部署之后不会生成流程实例,就无法进行流程的启动等操作。

部署之后,查看数据库,act_re_deployent表有我们刚才部署的流程

在act_ge_bytearray表上也有流程对应的资源,一般是bpmn图

在act_re_procdef表上应该会生成bpmn流程文档中process对应的流程定义:

这样流程就算完成部署了。

可以分析一下刚才App类中,deploy函数内的代码。activiti的部署由RepositoryService负责,而RepositoryService则委托DeploymentBuilder进行部署。这里使用了建造者模式。通过源码分析可知DeploymentBuilder为流程部署的实体DeploymentEntity进行属性设置,然后再调用deploy进行部署。部署了流程之后,下一章会介绍流程的启动。

扩展:

其实流程部署并不是一定需要通过bpmn文件。因为activiti会把bpmn文件中的元素转化到BpmnModel中。activiti还提供了一种编程式的方式去部署bpmn流程,就是用户可以新建一个BpmnModel,然后设置好流程中的元素,把BpmnModel部署到流程引擎中:

public void addBpmnModel() {
    SequenceFlow flow1 = new SequenceFlow();
    flow1.setId("flow1");
    flow1.setName("start->userTask1");
    flow1.setSourceRef("startEvent1");
    flow1.setTargetRef("userTask1");
    SequenceFlow flow2 = new SequenceFlow();
    flow2.setId("flow2");
    flow2.setName("userTask1->end");
    flow2.setSourceRef("userTask1");
    flow2.setTargetRef("endEvent1");
    BpmnModel bpmnModel = new BpmnModel();
    Process process = new Process();
    process.setId("secondBpmProcess");
    StartEvent startEvent = new StartEvent();
    startEvent.setId("startEvent1");
    startEvent.setOutgoingFlows(Arrays.asList(flow1));
    UserTask userTask1 = new UserTask();
    userTask1.setId("userTask1");
    userTask1.setName("userTask1");
    userTask1.setIncomingFlows(Arrays.asList(flow1));
    userTask1.setOutgoingFlows(Arrays.asList(flow2));
    EndEvent endEvent = new EndEvent();
    endEvent.setId("endEvent1");
    endEvent.setName("endEvent1");
    endEvent.setIncomingFlows(Arrays.asList(flow2));
    process.addFlowElement(startEvent);
    process.addFlowElement(flow1);
    process.addFlowElement(userTask1);
    process.addFlowElement(flow2);
    process.addFlowElement(endEvent);
    bpmnModel.addProcess(process);
    RepositoryService repositoryService = pe.getRepositoryService();
    DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
    deploymentBuilder.addBpmnModel("second", bpmnModel);
    deploymentBuilder.deploy();
}

这个部署的流程和上面的大致相同。可以查看act_re_deployent和act_ge_bytearray的效果,和之前的inputStream方式类似。

发布了39 篇原创文章 · 获赞 5 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/sadoshi/article/details/104636175