Activiti6--入门学习--信号边界事件

简介

版权声明:本文部分为CSDN博主「司马缸砸缸了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接

信号事件的定义

信号事件会引用一个已命名的信号,信号全局范围的事件(广播语义),会发送给所有激活的处理器。

触发信号事件

既可以通过bpmn节点由流程实例触发一个信号,也可以通过API触发。
手动触发信号:

// 把信号发送给全局所有订阅的处理器
RuntimeService.signalEventReceived(String signalName);
// 把信号发送给指定执行流
RuntimeService.signalEventReceived(String signalName, String executionId); 

查询信号事件的订阅

List<Execution> executions = runtimeService.createExecutionQuery()
      .signalEventSubscriptionName("alert")
      .list();  

信号事件范围

默认,信号会在流程引擎范围内进行广播。就是说, 你可以在一个流程实例中抛出一个信号事件,其他不同流程定义的流程实例 都可以监听到这个事件。然而,有时只希望在同一个流程实例中响应这个信号事件。 比如一个场景是,流程实例中的同步机制,如果两个或更多活动是互斥的。
如果想要限制信号事件的范围,可以使用信号事件定义的scope 属性 (不是BPMN2.0的标准属性):

<signal id="alertSignal" name="alert" activiti:scope"processInstance"/>

信号边界事件

例如有如下场景,系统提交工单后到达审批节点,在审批过程中,如果用户要修改工单,那么发送一个信号,使流程走到更改工单节点。

设计流程图
注意
设置信号边界事件之前,需要定义信号否则设置不了

在这里插入图片描述
流程文件bpmn

<?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="m1595925267697" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="signal" isClosed="false" isExecutable="true" name="Signal" processType="None">
    <startEvent id="_2" name="StartEvent"/>
    <userTask activiti:assignee="user1" activiti:exclusive="true" id="_3" name="填写工单"/>
    <userTask activiti:assignee="user2" activiti:exclusive="true" id="_4" name="审批"/>
    <userTask activiti:assignee="user3" activiti:exclusive="true" id="_5" name="更改工单"/>
    <endEvent id="_6" name="EndEvent"/>
    <boundaryEvent attachedToRef="_4" cancelActivity="false" id="_7" name="BoundaryEvent">
      <signalEventDefinition id="_7_ED_1" signalRef="SIG_1"/>
    </boundaryEvent>
    <sequenceFlow id="_8" sourceRef="_2" targetRef="_3"/>
    <sequenceFlow id="_9" sourceRef="_3" targetRef="_4"/>
    <sequenceFlow id="_10" sourceRef="_4" targetRef="_6"/>
    <sequenceFlow id="_11" sourceRef="_7" targetRef="_5"/>
    <sequenceFlow id="_12" sourceRef="_5" targetRef="_3"/>
  </process>
  <signal id="SIG_1" name="changeSignal"/>
  <signal id="SIG_2" name="changeSignal1"/>
  <bpmndi:BPMNDiagram documentation="background=#000000;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="signal">
      <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
        <omgdc:Bounds height="32.0" width="32.0" x="10.0" y="85.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
        <omgdc:Bounds height="55.0" width="85.0" x="140.0" y="75.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
        <omgdc:Bounds height="72.0" width="95.0" x="370.0" y="70.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="72.0" width="95.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5">
        <omgdc:Bounds height="55.0" width="85.0" x="255.0" y="245.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6">
        <omgdc:Bounds height="32.0" width="32.0" x="590.0" y="80.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_7" id="Shape-_7">
        <omgdc:Bounds height="32.0" width="32.0" x="400.0" y="110.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="30.0" y="40.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_12" id="BPMNEdge__12" sourceElement="_5" targetElement="_3">
        <omgdi:waypoint x="255.0" y="272.5"/>
        <omgdi:waypoint x="225.0" y="102.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_2" targetElement="_3">
        <omgdi:waypoint x="42.0" y="101.0"/>
        <omgdi:waypoint x="140.0" y="102.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_3" targetElement="_4">
        <omgdi:waypoint x="225.0" y="102.5"/>
        <omgdi:waypoint x="370.0" y="106.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_11" id="BPMNEdge__11" sourceElement="_7" targetElement="_5">
        <omgdi:waypoint x="400.0" y="126.0"/>
        <omgdi:waypoint x="340.0" y="272.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="_4" targetElement="_6">
        <omgdi:waypoint x="465.0" y="106.0"/>
        <omgdi:waypoint x="590.0" y="96.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

测试类

package com.yb.activiti6;

import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.List;

/**
 * @author liangjie@itcast.cn
 * @version 1.0
 * @date 2020/7/23
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiDemoTest08 {
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private IdentityService identityService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ProcessEngine processEngine;

    @Autowired
    private HistoryService historyService;


    /**
     * 发布流程,测试信号边界事件
     * @throws IOException
     */
    @Test
    public void deploymentProcesses_zip(){
        Deployment deploy = repositoryService.createDeployment()
                .name("测试-信号边界事件-1")//创建流程名称
                .addClasspathResource("processes/activiti_signal.bpmn")//指定zip完成部署
                .addClasspathResource("processes/activiti_signal.png")
                .deploy();
        System.out.println("部署id:"+deploy.getId());
        System.out.println("部署名称:"+deploy.getName());

    }

    /**
     * 启动流程,测试信号边界事件
     */
    @Test
    public void startProcess() throws InterruptedException{
        //可根据id,key,message启动流程
        ProcessInstance parallel = runtimeService.startProcessInstanceByKey("signal");
        System.out.println("流程实例id:"+parallel.getId());
        System.out.println("流程定义id:"+parallel.getProcessDefinitionId());
        //睡一会
        Thread.sleep(1000 * 10);
        System.out.println("========================================================");
        List<Task> list = taskService.createTaskQuery().taskAssignee("user1").list();
        for (Task task : list) {
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("任务创建时间:" + task.getCreateTime());
            System.out.println("任务委派人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
            //完成任务
            taskService.complete(task.getId());
        }


        // 查询任务
        List<Task> list1 = taskService.createTaskQuery() // 创建任务查询
                .taskAssignee("user2") // 指定某个人
                .list();
        for (Task task : list1) {
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("任务创建时间:" + task.getCreateTime());
            System.out.println("任务委派人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
        }
        //睡一会
        Thread.sleep(1000 * 10);
        System.out.println("========================================================");
        //发送信号
        runtimeService.signalEventReceived("changeSignal");
        //睡一会
        Thread.sleep(1000 * 10);
        // 查询任务
        List<Task> list2 = taskService.createTaskQuery() // 创建任务查询
                .taskAssignee("user3") // 指定某个人
                .list();
        for (Task task : list2) {
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("任务创建时间:" + task.getCreateTime());
            System.out.println("任务委派人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
        }
    }

    /**
     * 查看任务
     */
    @Test
    public void queryTask(){
        List<Task> taskList = taskService.createTaskQuery() // 创建任务查询
                .taskAssignee("user3") // 指定某个人
                .list();
        for (Task task : taskList) {
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("任务创建时间:" + task.getCreateTime());
            System.out.println("任务委派人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
        }
    }

    /**
     * 提交任务
     */
    @Test
    public void completeTask2(){
        
        String taskId = "2511";
        taskService.complete(taskId);
    }


    /**
     * 发送信号
     */
    @Test
    public void eventReceived() {
        // 可以查询所有订阅了特定信号事件的执行流
        List<Execution> executions = runtimeService.createExecutionQuery()
                .signalEventSubscriptionName("changeSignal")
                .list();
        // 把信号发送给全局所有订阅的处理器(广播语义)
        runtimeService.signalEventReceived("changeSignal");

        // 只把信息发送给指定流程的执行
        runtimeService.signalEventReceived("changeSignal", executions.get(0).getId());
    }


    /**
     * 查询流程状态(判断流程走到哪一个节点)
     */
    @Test
    public void isProcessActive(){
//        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
//                .processInstanceId("2501")
//                .singleResult();
//
//        if(processInstance==null){
//            System.out.println("该流程已经结束");
//        }else {
//            System.out.println("该流程尚未结束");
//            //获取任务状态(该方式无法获取节点信息)
//            System.out.println("节点ID:"+processInstance.getActivityId());
//        }
        HistoricActivityInstance hiv = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId("55001")
                .unfinished()
                .singleResult();
        if(hiv==null){
            System.out.println("该流程已结束");
        }else {
            System.out.println("该流程未结束,节点id为:"+hiv.getActivityId()
                                +"  节点名称为:"+hiv.getActivityName()
                                +"  节点类型:"+hiv.getActivityType()
                                +"  节点代理人:"+hiv.getAssignee());
        }
    }
    /**
     * 历史记录
     */
    @Test
    public void historyActiviti(){
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId("2501")
                .list();

        for (HistoricActivityInstance his : list) {
            System.out.println("活动id:"+ his.getActivityId()
                    +" 审批人: "+ his.getAssignee()
                    +" 任务id: "+ his.getTaskId());
            System.out.println("===========================");
        }
    }
}

当前测试流程走向:
部署流程→启动流程→填写工单→审批→发送信号→触发信号边界事件→更改工单

效果:
在这里插入图片描述
提交更改工单的任务
当前流程走向:
部署流程→启动流程→填写工单→审批→发送信号→触发信号边界事件→更改工单(完成)→填写工单
在这里插入图片描述
然后完成填写工单和审批,流程结束。
在这里插入图片描述
在这里插入图片描述
到此信号边界事件测试完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值