BPMN2.0中的顺序流、网关和子流程

目录

一、顺序流与网关

1. 顺序流

2. 网关

2.1 单一网关顺序流实例

2.2 并行网关实例

2.3 包容性网关实例

2.4 支持事件网关实例

二、子流程

1. 子流程

2. 事件子流程


一、顺序流与网关

1. 顺序流

备注: 一般情况下只有一条直线加一个箭头

2. 网关

  • 单一网关(Exclusive Gateway):一条路走下去

  • 并行网关(Parallel Gateway):多条路可以同时走下去

  • 包容性网关(Inclusive Gateway):继支持多条路同时走也支持条件表达式

  • 基于事件网关(Event-based Gateway):等待事件触发,一个事件触发了其他事件都会失效

2.1 单一网关顺序流实例

   备注:前两条为条件顺序流,第三条为默认顺序流

   单一网关特点: 分支判断、只能选一、支持默认

 单一网关测试代码实现:

public class GatewayTest {
    private static final Logger LOGGER = LoggerFactory.getLogger(GatewayTest.class);

    @Rule
    public ActivitiRule activitiRule = new ActivitiRule();

    @Test
    @Deployment(resources = "my-process-exclusiveGateway1.bpmn20.xml")
    public void test(){
        Map<String, Object> variables = new HashMap<>();
        variables.put("score", 70);
        ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process", variables);
        Task task = activitiRule.getTaskService().createTaskQuery().singleResult();
        LOGGER.info("task.name = {}",task.getName());
    }
}

 测试效果:

2.2 并行网关实例

并发网关的特点:流程并发、分支、合并、忽略条件、非对称

并行网关测试代码实现:

@Test
@Deployment(resources = "my-process-parallelGateway1.bpmn20.xml")
public void parallelTest(){
    ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
    List<Task> tasks = activitiRule.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).listPage(0, 100);
    for(Task task : tasks){
        LOGGER.info("task.name = {}",task.getName());
        activitiRule.getTaskService().complete(task.getId());
    }
    LOGGER.info("tasks.size = {}", tasks.size());
    Task task = activitiRule.getTaskService().createTaskQuery().singleResult();
    LOGGER.info("task.name = {}", task.getName());
}

测试效果:

2.3 包容性网关实例

包容性网关的特点:支持并发、分支、合并、支持条件、非对称

2.4 支持事件网关实例

以哪个事件先发生为准:比如信号事件和定时任务,在10分钟的定时内,如果信号事件先发生,则先执行信号任务,并清理其他事件。

包容性网关的特点:流程暂停、事件订阅、捕获事件、单一执行

二、子流程

1. 子流程

Activiti中的子流程分两种:Sub-Process and Call Activities

子流程分类:

  • 子流程(Sub-Process)

  • 事件子流程(Event Sub-Process)

  • 事物子流程(Transaction Sub-Process)

  • 调用式子流程(Call Activiti)

子流程图示

子流程实例

子流程中:共性的东西可以拿出来共同处理,比如异常处理等;子流程与其他流程有流程边界。

 注:子过程抛出的事件都可以在边界中捕获。

子流程特点:分层建模、数据隔离、事件范围、边界事件

(1)流程定义文件

主要是需要一个

<subProcess>

 <...><!--其中也需要有开始和结束节点-->

重要的代码:

<serviceTask id="pay" name="确认支付" activiti:class="com.syc.activiti.example.MyPayJavaDelegate"/>

<serviceTask id="take" name="确认收货" activiti:class="com.syc.activiti.example.MyTakeJavaDelegate"/>

 </subProcess>

还需要一个边界事件:

<boundaryEvent id="boundary" attachedToRef="subProcess">

    <errorEventDefinition errorRef="bpmnError"></errorEventDefinition>

</boundaryEvent>

(2)编写两个Delegate

一个是MyPayJavaDelegate,一个是MyTakeJavaDelegate,两个类代码类似。

public class MyPayJavaDelegate implements JavaDelegate, Serializable {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyPayJavaDelegate.class);

    @Override
    public void execute(DelegateExecution execution) {
        LOGGER.info("run my pay java delegate {}", this);
    }
}

 (3)编写测试类SubProcessTest

@Test
@Deployment(resources = "my-process-subprocess1.bpmn20.xml")
public void testSubProcess(){
    ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
    Task task = activitiRule.getTaskService().createTaskQuery().singleResult();
    LOGGER.info("task.name = {}",task.getName());
}

 (4)测试效果

最终指向的是订单完成节点。

(5)测试异常情况

在MyPayJavaDelegate类中抛出异常

public class MyPayJavaDelegate implements JavaDelegate, Serializable {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyPayJavaDelegate.class);
    @Override
    public void execute(DelegateExecution execution) {
        LOGGER.info("run my pay java delegate {}", this);
        Object errorflag = execution.getVariable("errorflag");
        if(Objects.equals(errorflag, true)){
            throw new BpmnError("bpmnError");
        }
        LOGGER.info("pay error");
    }
}

 测试效果

2. 事件子流程

   说明:事件子流程可以捕获任意节点抛出的错误事件

   流程定义文件子流程代码:

<subProcess id="subProcess" triggeredByEvent="true">
    <startEvent id="startSub">
        <errorEventDefinition errorRef="bpmnError"></errorEventDefinition>
    </startEvent>
    <endEvent id="endSub"/>
    <userTask id="orderError" name="异常处理"/>
    <sequenceFlow sourceRef="startSub" targetRef="orderError"/>
    <sequenceFlow sourceRef="orderError" targetRef="endSub"/>
</subProcess>

测试代码无需修改,测试效果如上,能够打印出  task.nam = "异常处理"

事件子流程可以获取到局部变量的信息:

例如在MyPayJavaDelegate中添加局部变量key2的值为value2:

execution.getParent().setVariableLocal("key2", "value2");
原创文章 97 获赞 43 访问量 1万+

猜你喜欢

转载自blog.csdn.net/shao_yc/article/details/105342329