边界事件:边界事件属于一种特殊的中间事件。区别是: 中间事件 可以单独作为流程元素存在于流程中,而 边界事件 必须附属于某个流程元素(如任务、子流程等)。边界事件是Catching事件。
注意:补偿事件的连接线需要用association,association必须放在所有标签最后。
<process id="myProcess_1" isClosed="false" isExecutable="true"
processType="None">
<startEvent id="startEvent1" name="StartEvent"/>
<userTask activiti:exclusive="true" id="userTask1" name="初级工程师维修"/>
<!--cancelActivity属性是触发边界事件后,原流程是否取消,为true是取消,取消是在数据库中删除对应的数据-->
<boundaryEvent attachedToRef="userTask1" cancelActivity="true" id="boundaryEvent1">
<timerEventDefinition id="boundaryEvent1_ED_1">
<!--定时一分钟-->
<timeDuration>PT1M</timeDuration>
</timerEventDefinition>
</boundaryEvent>
<endEvent id="endEvent1" name="EndEvent"/>
<userTask activiti:exclusive="true" id="userTask2" name="中级工程师维修"/>
<sequenceFlow id="_7" sourceRef="startEvent1" targetRef="userTask1"/>
<sequenceFlow id="_8" sourceRef="userTask1" targetRef="endEvent1"/>
<sequenceFlow id="_9" sourceRef="boundaryEvent1" targetRef="userTask2"/>
<sequenceFlow id="_10" sourceRef="userTask2" targetRef="endEvent1"/>
</process>
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("timer-boundary-event.bpmn").deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
//首先由初级工程师维修
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
System.out.println("当前任务:" + task.getName());
//等定时器1分钟过完,需要比一分钟时间长,防止步骤没执行完
Thread.sleep(100 * 1000);
//定时器时间到了后会触发定时器边界事件,任务转到中级工程师
task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
System.out.println("当前任务:" + task.getName());
processEngine.close();
System.exit(0);
<process id="process1" name="process">
<startEvent id="startEvent1" name="startEvent"></startEvent>
<subProcess id="subProcess1" name="subProcess">
<startEvent id="startEvent2" name="startEvent"></startEvent>
<serviceTask id="serviceTask1" name="Throw Error Task"
activiti:class="com.xjf.test.delegate.ThrowErrorDelegate"></serviceTask>
<endEvent id="endEvent1" name="endEvent"></endEvent>
<sequenceFlow id="_1" sourceRef="startEvent2" targetRef="serviceTask1"></sequenceFlow>
<sequenceFlow id="_2" sourceRef="serviceTask1" targetRef="endEvent1"></sequenceFlow>
</subProcess>
<boundaryEvent id="boundaryEvent1" attachedToRef="subProcess1" cancelActivity="false">
<!--引入的错误引用没有定义时,则errorCode就是引用的字符串,此处为“abc”-->
<errorEventDefinition errorRef="abc"></errorEventDefinition>
</boundaryEvent>
<userTask id="ErrorTask" name="ErrorTask"></userTask>
<userTask id="EndTask" name="EndTask"></userTask>
<endEvent id="endEvent2" name="endEvent"></endEvent>
<sequenceFlow id="_3" sourceRef="startEvent1" targetRef="subProcess1"></sequenceFlow>
<sequenceFlow id="_4" sourceRef="boundaryEvent1" targetRef="ErrorTask"></sequenceFlow>
<sequenceFlow id="_5" sourceRef="subProcess1" targetRef="EndTask"></sequenceFlow>
<sequenceFlow id="_6" sourceRef="EndTask" targetRef="endEvent2"></sequenceFlow>
</process>
String errorCode = "abc";
System.out.println("抛出错误:errorCode=" + errorCode);
throw new BpmnError(errorCode);
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("error-boundary-event.bpmn").deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
System.out.println("当前任务:" + task.getName());
processEngine.close();
System.exit(0);
<process id="process" isClosed="false" name="process" processType="None">
<startEvent id="startEvent" name="startEvent"/>
<userTask activiti:exclusive="true" id="checkContact" name="查看合同"/>
<userTask activiti:exclusive="true" id="confirmContact" name="确认合同"/>
<boundaryEvent attachedToRef="confirmContact" cancelActivity="true" id="boundaryEvent">
<signalEventDefinition id="boundaryEvent_ED_1" signalRef="contactChangeSignal"/>
</boundaryEvent>
<userTask activiti:exclusive="true" id="contactChange" name="合同变更"/>
<userTask activiti:exclusive="true" id="signContact" name="签订合同"/>
<endEvent id="endEvent" name="endEvent"/>
<sequenceFlow id="_2" sourceRef="startEvent" targetRef="checkContact"/>
<sequenceFlow id="_3" sourceRef="checkContact" targetRef="confirmContact"/>
<sequenceFlow id="_4" sourceRef="boundaryEvent" targetRef="contactChange"/>
<sequenceFlow id="_5" sourceRef="contactChange" targetRef="checkContact"/>
<sequenceFlow id="_6" sourceRef="confirmContact" targetRef="signContact"/>
<sequenceFlow id="_7" sourceRef="signContact" targetRef="endEvent"/>
</process>
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("signal-boundary-event.bpmn").deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
//启动两个流程实例
ProcessInstance pInstance1 = runtimeService.startProcessInstanceById(processDefinition.getId());
ProcessInstance pInstance2 = runtimeService.startProcessInstanceById(processDefinition.getId());
//将实例一进行到确认合同
Task pInstance1Task = taskService.createTaskQuery().processInstanceId(pInstance1.getId()).singleResult();
taskService.complete(pInstance1Task.getId());
pInstance1Task = taskService.createTaskQuery().processInstanceId(pInstance1.getId()).singleResult();
System.out.println("实例一当前任务:" + pInstance1Task.getName());
//将实例二进行到确认合同
Task pInstance2Task = taskService.createTaskQuery().processInstanceId(pInstance2.getId()).singleResult();
taskService.complete(pInstance2Task.getId());
pInstance2Task = taskService.createTaskQuery().processInstanceId(pInstance2.getId()).singleResult();
System.out.println("实例二当前任务:" + pInstance2Task.getName());
//发送合同变更信号
runtimeService.signalEventReceived("change");
//根据流程定义查询任务
List<Task> list = taskService.createTaskQuery().processDefinitionId(processDefinition.getId()).list();
list.forEach(task -> System.out.println("流程实例id:" + task.getProcessInstanceId() + "----------------任务:" + task.getName()));
processEngine.close();
System.exit(0);
<process id="process" isClosed="false" name="process" processType="None">
<startEvent id="startEvent" name="startEvent"/>
<serviceTask activiti:exclusive="true" id="transferOut" name="转出银行扣款"
activiti:class="com.xjf.test.delegate.TransferOutDelegate"/>
<boundaryEvent attachedToRef="transferOut" cancelActivity="true" id="transferOutBoundary">
<compensateEventDefinition id="transferOutBoundary_ED_1" waitForCompletion="true"/>
</boundaryEvent>
<!--isForCompensation需要指明是补偿事件-->
<serviceTask activiti:exclusive="true" id="transferOutCancel" name="转出银行取消"
activiti:class="com.xjf.test.delegate.TransferOutCancelDelegate" isForCompensation="true"/>
<serviceTask activiti:exclusive="true" id="transferIn" name="转入银行加款"
activiti:class="com.xjf.test.delegate.TransferInDelegate"/>
<boundaryEvent attachedToRef="transferIn" cancelActivity="true" id="transferInBoundary">
<compensateEventDefinition id="transferInBoundary_ED_1" waitForCompletion="true"/>
</boundaryEvent>
<serviceTask activiti:exclusive="true" id="transferInCancel" name="转入银行取消"
activiti:class="com.xjf.test.delegate.TransferInCancelDelegate" isForCompensation="true"/>
<sequenceFlow id="_2" sourceRef="startEvent" targetRef="transferOut"/>
<sequenceFlow id="_3" sourceRef="transferOut" targetRef="transferIn"/>
<serviceTask activiti:exclusive="true" id="verifyTransfer" name="验证转账结果"
activiti:class="com.xjf.test.delegate.VerifyTransferDelegate"/>
<boundaryEvent attachedToRef="verifyTransfer" cancelActivity="true" id="errorBoundary">
<errorEventDefinition errorRef="transferError" id="errorBoundary_ED_1"/>
</boundaryEvent>
<intermediateThrowEvent id="intermediateThrowEvent" name="NoneThrowEvent">
<compensateEventDefinition id="intermediateThrowEvent_ED_1" waitForCompletion="true"/>
</intermediateThrowEvent>
<endEvent id="normalEnd" name="正常结束"/>
<endEvent id="compensateEnd" name="补偿结束"/>
<sequenceFlow id="_4" sourceRef="transferIn" targetRef="verifyTransfer"/>
<sequenceFlow id="_5" sourceRef="verifyTransfer" targetRef="normalEnd"/>
<sequenceFlow id="_6" sourceRef="errorBoundary" targetRef="intermediateThrowEvent"/>
<sequenceFlow id="_7" sourceRef="intermediateThrowEvent" targetRef="compensateEnd"/>
<association associationDirection="None" id="a1" sourceRef="transferOutBoundary"
targetRef="transferOutCancel"/>
<association associationDirection="None" id="a2" sourceRef="transferInBoundary"
targetRef="transferInCancel"/>
</process>
对应的委托类:
public class TransferInCancelDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println("转入银行---取消增加金额");
}
}
public class TransferInDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println("转入银行---增加金额");
}
}
public class TransferOutCancelDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println("转出银行---取消扣减金额");
}
}
public class TransferOutDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println("转出银行---扣减金额");
}
}
public class VerifyTransferDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
//从执行流中获取变量
boolean flag = (boolean)delegateExecution.getVariable("result");
if (flag){
System.out.println("转账成功");
}else {
System.out.println("转账失败,抛出错误");
throw new BpmnError("transferError");
}
}
}
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("compensation-boundary-event.xml").deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
//存放变量,记录转账是否成功
Map<String,Object> vars = new HashMap<>();
vars.put("result",false);
runtimeService.startProcessInstanceById(processDefinition.getId(), vars);
processEngine.close();
System.exit(0);
《疯狂Workflow讲义第二版》