1、什么是BPMN
业务流程建模与标注(Business Process Model and Notation,BPMN) ,描述流程的基本符号,包括这些图元如何组合成一个业务流程图(Business Process Diagram)
Eclispse画出流程,有两个文件bpmn文件和png文件,其中bpmn文件又可以叫做流程定义文件,它需要遵循BPMN语言规范.png:就是一个单纯的图片,没有任何作用.
2、流程(process)
bpmn文件一个流程的根元素。一个流程就代表一个工作流。
3、顺序流
3.1、什么是顺序流
顺序流是连接两个流程节点的连线,代表一个节点的出口。流程执行完一个节点后,会沿着节点的所有外出顺序流继续执行。 就是说,BPMN 2.0默认的行为就是并发的: 两个外出顺序流会创造两个单独的,并发流程分支。
顺序流主要由4个属性组成:
Id: 唯一标示,用来区分不同的顺序流
sourceRef:连线的源头节点ID
targetRef:连线的目标节点ID
name(可选):连线的名称,不涉及业务,主要用于显示。多出口原则要设置。
说明:
1)结束节点没有出口
其他节点有一个或多个出口。如果有一个出口,则代表是一个单线流程;如果有多个出口,则代表是开启并发流程。
3.2、分支流程-流程图
3.3、公共代码抽取
package cn.itsource.activiti.day02;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
public class BaseBpmn {
private ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
//自己类和子类都可能使用:使用protected修饰
protected RepositoryService repositoryService = processEngine.getRepositoryService();
protected RuntimeService runtimeService = processEngine.getRuntimeService();
protected TaskService taskService = processEngine.getTaskService();
/**
*
* @param name 部署流程的名字
* @param resourceName 加载资源的名字前缀
* @return
*/
protected Deployment deploy(String name, String resourceName) {
//创建核心
//获取服务
//做事情
// this.getClass().getClassLoader().getResourceAsStream("LeaveFlow.bpmn");从classpath下面加载
// this.getClass().getResourceAsStream("/LeaveFlow.bpmn");//从classpath下面加载
// this.getClass().getResourceAsStream("LeaveFlow.bpmn");//从当前类当前包加载(采纳)
// this.getClass().getResourceAsStream("./LeaveFlow.bpmn");//从当前类当前包加载(采纳)
String resourceNameBpmn=resourceName+".bpmn";
String resourceNamePng=resourceName+".png";
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
deploymentBuilder.name(name)
.addInputStream(resourceNameBpmn, this.getClass().getResourceAsStream(resourceNameBpmn))
.addInputStream(resourceNamePng, this.getClass().getResourceAsStream(resourceNamePng));
Deployment deployment = deploymentBuilder.deploy();
return deployment;
}
/**
*
* @param processDefinitionKey 启动流程的定义的key
*/
protected ProcessInstance startProcess(String processDefinitionKey) {
return runtimeService.startProcessInstanceByKey(processDefinitionKey);
}
/**
* 在一个流程实例中,一个办理人只有一个唯一的任务
* @param processInstanceId 流程实例id
* @param assignee 办理人
* @return
*/
protected Task queryPersonalTask(String processInstanceId, String assignee) {
return taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.taskAssignee(assignee)
.singleResult();
}
}
3.4、分支流程-测试代码
3.4.1、辅助代码:
@Test
public void deployTest() throws Exception {
Deployment deployment = deploy("报销申请","SequesceFlowTest");
System.out.println("deploymentId:"+deployment.getId());
}
@Test
public void startProcessTest() throws Exception {
String processDefinitionKey="SequesceFlowTest";
ProcessInstance processInstance = startProcess(processDefinitionKey);
System.out.println("ProcessInstanceId:"+processInstance.getId());//2501
}
3.4.2、测试驳回:
//测试驳回
/**
* ①:先完成报销申请,
* ②:走到审批的时候,设置一个flag的流程变量为flase,驳回
* ③:回到①,在完成报销申请
* ④:审批人又得到审批审批任务
* @throws Exception
*/
@Test
public void notPassTest() throws Exception {
//①:先完成报销申请,
String processInstanceId="2501";
String assignee="小明";
Task applyTask = queryPersonalTask(processInstanceId,assignee);
System.out.println("获取申请任务:"+applyTask);
//先完成报销申请
taskService.complete(applyTask.getId());
assignee="小刚";
Task approveTask = queryPersonalTask(processInstanceId,assignee);
System.out.println("获取审批任务:"+applyTask);
// ②:走到审批的时候,设置一个flag的流程变量为flase
taskService.setVariable(approveTask.getId(),"flag", "false");
//驳回
taskService.complete(approveTask.getId());
//④:审批人又得到审批审批任务
assignee="小明";
applyTask &#