Activiti的ACT_GE_BYTEARRAY用于保存二进制文件,所以理论上来说,它什么都能部署
1. DeploymentBuilder对象
1.1 说明
Deployment对象映射到ACT_RE_DEPLOYMENT上的一条数据。RepositoryService的createDeployment()方法获取DeploymentBuilder对象,用于构建Deployment对象。
1.2 DeploymentBuilder的API
2. 添加BPMN模型
2.1 部署压缩文件
创建压缩文件test.zip,目录结构如下
代码
package com.study.deployment;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import java.io.InputStream;
import java.util.zip.ZipInputStream;
public class DeployZipFile {
public static void main(String[] args) throws Exception{
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService rs = engine.getRepositoryService();
ClassLoader classLoader = DeployZipFile.class.getClassLoader();
InputStream stream = classLoader.getResourceAsStream("test.zip");
DeploymentBuilder deploymentBuilder = rs.createDeployment().addZipInputStream(new ZipInputStream(stream));
Deployment deployment = deploymentBuilder.deploy();
engine.close();
}
}
执行结果,ACT_RE_DEPLOYMENT新增一条id为7501的数据
ACT_GE_BYTEARRAY出现两条与之相关的记录,即是压缩包中的两个文本文件
2.2 通过BpmnModel创建流程文件
可以通过java代码实现动态流程,动态生成流程文件
2.2.1 java代码
package com.study.deployment;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.DeploymentBuilder;
public class BpmnTest {
public static void main(String[] args) {
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService rs = engine.getRepositoryService();
DeploymentBuilder deployment = rs.createDeployment();
deployment.addBpmnModel("oa",createBpmnModel()).deploy();
engine.close();
}
private static BpmnModel createBpmnModel(){
BpmnModel bpmnModel = new BpmnModel();
Process process = new Process();
process.setId("process1");
process.setName("process 1");
bpmnModel.addProcess(process);
FlowElement startEvent = new StartEvent();
startEvent.setId("startEvent");
startEvent.setName("start event");
process.addFlowElement(startEvent);
FlowElement userTask = new UserTask();
userTask.setId("userTask");
userTask.setName("user task");
process.addFlowElement(userTask);
FlowElement endEvent = new EndEvent();
startEvent.setId("endEvent");
startEvent.setName("end event");
process.addFlowElement(endEvent);
process.addFlowElement(new SequenceFlow("startEvent","userTask"));
process.addFlowElement(new SequenceFlow("userTask","endEvent"));
return bpmnModel;
}
}
2.2.2 执行结果
1) ACT_GE_BYTEARRAY表中新增了oa的数据
2) 生成二进制文件中的内容
<?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="process1" name="process 1" isExecutable="true">
<startEvent id="endEvent" name="end event"></startEvent>
<userTask id="userTask" name="user task"></userTask>
<endEvent></endEvent>
<sequenceFlow sourceRef="startEvent" targetRef="userTask"></sequenceFlow>
<sequenceFlow sourceRef="userTask" targetRef="endEvent"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_process1">
<bpmndi:BPMNPlane bpmnElement="process1" id="BPMNPlane_process1"></bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
2.2.3 分析对比
比较java代码与生成的xml文件,可以发现一一对应。利用这个特性,我们可以在运行时动态的生成流程,极大的增强了业务的灵活性。
3. 部署验证
3.1 关闭格式验证
deploymentBuilder.disableSchemaValidation();
3.2 关闭流程验证
deploymentBuilder.disableBpmnValidation();
4. 查询部署资源
4.1 查询文件
4.1.1 准备测试文件
4.1.2 代码
package com.study.query;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import java.io.IOException;
import java.io.InputStream;
public class QueryFile {
public static void main(String[] args) throws IOException {
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("my_test.txt").deploy();
//查询已部署的文件内容
InputStream is = repositoryService.getResourceAsStream(deployment.getId(), "my_test.txt");
int count = is.available();
byte buffer[] = new byte[count];
is.read(buffer);
String content = new String(buffer);
System.out.println(content);//This is my content!
}
}
4.2 查询流程文件
查询流程文件需要使用repositoryService的getProcessModel方法
代码
package com.study.query;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import java.io.IOException;
import java.io.InputStream;
public class QueryBpmn {
public static void main(String[] args) throws IOException {
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("first.bpmn").deploy();
//查询已部署的文件内容
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
deploymentId(deployment.getId()).singleResult();
InputStream processModelStream = repositoryService.getProcessModel(processDefinition.getId());
int count = processModelStream.available();
byte buffer[] = new byte[count];
processModelStream.read(buffer);
String content = new String(buffer);
System.out.println(content);
}
}
结果:
11:19:11,335 [main] INFO org.activiti.engine.compatibility.DefaultActiviti5CompatibilityHandlerFactory - Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled.
11:19:11,388 [main] INFO org.activiti.engine.impl.ProcessEngineImpl - ProcessEngine default created
11:19:11,397 [main] INFO org.activiti.engine.ProcessEngines - initialised process engine default
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 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" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1563584736183" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="leave" isClosed="false" isExecutable="true" processType="None">
<startEvent id="_2" name="StartEvent"/>
<userTask activiti:exclusive="true" id="_3" name="Worker raise a leave request"/>
<userTask activiti:exclusive="true" id="_4" name="Boss audit"/>
<endEvent id="_5" name="EndEvent"/>
<sequenceFlow id="_6" sourceRef="_2" targetRef="_3"/>
<sequenceFlow id="_7" sourceRef="_3" targetRef="_4"/>
<sequenceFlow id="_8" sourceRef="_4" targetRef="_5"/>
</process>
...
4.3 查询流程图
查询图片需要使用repositoryService的getProcessDiagram方法
代码
package com.study.query;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.util.ReflectUtil;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
public class QueryPic {
public static void main(String[] args) throws IOException {
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("first.bpmn").deploy();
//查询已部署的文件内容
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
deploymentId(deployment.getId()).singleResult();
InputStream is = repositoryService.getProcessDiagram(processDefinition.getId());
BufferedImage image = ImageIO.read(is);
URL url = QueryPic.class.getClassLoader().getResource(".");
File file = new File(url.getPath()+"/result.png");
if(!(file.exists())) file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
ImageIO.write(image,"png",fos);
fos.close();
is.close();
engine.close();
}
}
结果
结论
只部署流程文件,也能生成流程图
5. 删除部署数据
deployment是最上层的概念,有了deployment才有了流程定义、历史数据、运行时数据
5.1 注意点
- 不管是否指定级联,都会删除部署相关的身份数据、流程定义数据、流程资源与部署数据。
- 如果设置为级联删除,则会将运行的流程实例、流程任务以及流程实例的历史数据删除。
- 如果不级联删除,但是存在运行时数据,例如还有流程实例,就会删除失败。
5.2 代码
RepositoryService
/**
* Deletes the given deployment and cascade deletion to process instances, history process instances and jobs.
*
* @param deploymentId
* id of the deployment, cannot be null.
*/
void deleteDeployment(String deploymentId, boolean cascade);