前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2023最新版本Activiti7系列-监听器讲解

2023最新版本Activiti7系列-监听器讲解

作者头像
用户4919348
发布2023-08-09 19:36:17
2.4K0
发布2023-08-09 19:36:17
举报
文章被收录于专栏:波波烤鸭
监听器

1.执行监听器

  在流程实例执行过程中触发某个事件时,Activiti提供的执行监听器可以捕获该事件并执行相应的外部的Java代码,或者对指定的表达式求值。在流程实例执行过程中触发某个事件时,Activiti提供的执行监听器可以捕获该事件并执行相应的外部的Java代码,或者对指定的表达式求值。

  • start:开始事件
  • take:执行事件,只能在顺序流中
  • end:结束事件

具体通过案例来介绍

对应的执行监听器完成的生命周期:

然后在这个过程中我们可以配置监听器的方式:

  1. 直接配置class:需要配置实现了ExecutionListener接口的实现类型
  2. DelegateExpression:需要从Spring容器中获取实现了ExecutionListener接口的实现类
  3. Expression:需要从Spring中获取对应的bean对象及要调用的相关的方法

上面案例中完整的xml文件:

代码语言:javascript
复制
<?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/processdef">
  <process id="execution-listener1" name="execution-listener1" isExecutable="true">
    <documentation>execution-listener1</documentation>
    <startEvent id="start-el1" name="开始节点">
      <extensionElements>
        <activiti:executionListener event="start" class="com.boge.activiti.execution.ExecutionListener1">
          <activiti:field name="msg1">
            <activiti:string><![CDATA[boge666]]></activiti:string>
          </activiti:field>
          <activiti:field name="msg2">
            <activiti:expression><![CDATA[${msg2}]]></activiti:expression>
          </activiti:field>
        </activiti:executionListener>
        <activiti:executionListener event="end" class="com.boge.activiti.execution.ExecutionListener1">
          <activiti:field name="msg1">
            <activiti:string><![CDATA[boge-end]]></activiti:string>
          </activiti:field>
          <activiti:field name="msg2">
            <activiti:string><![CDATA[boge-msg2-end]]></activiti:string>
          </activiti:field>
        </activiti:executionListener>
      </extensionElements>
    </startEvent>
    <userTask id="sid-065D83B9-2D5A-4770-A1E8-A1D0A154DD86" name="用户节点1" activiti:assignee="s1">
      <extensionElements>
        <activiti:executionListener event="start" expression="${executionListener2.test1(execution)}"></activiti:executionListener>
        <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>
    <endEvent id="sid-C8D80560-62C9-44CE-AE7A-65235F11B7F6"></endEvent>
    <sequenceFlow id="sid-FF78808D-D503-4B50-9CB8-14079609F480" sourceRef="sid-C1F4513F-24AD-44A3-8596-B51E2815D604" targetRef="sid-C8D80560-62C9-44CE-AE7A-65235F11B7F6"></sequenceFlow>
    <userTask id="sid-C1F4513F-24AD-44A3-8596-B51E2815D604" name="用户节点2"></userTask>
    <sequenceFlow id="sid-157E09A5-8D4C-4D96-B938-EFC3863CE682" name="顺序流1" sourceRef="start-el1" targetRef="sid-065D83B9-2D5A-4770-A1E8-A1D0A154DD86"></sequenceFlow>
    <sequenceFlow id="sid-372284A1-CE05-4FCA-97C3-3DFB49B55CE6" name="顺序流2" sourceRef="sid-065D83B9-2D5A-4770-A1E8-A1D0A154DD86" targetRef="sid-C1F4513F-24AD-44A3-8596-B51E2815D604">
      <extensionElements>
        <activiti:executionListener event="take" delegateExpression="${executionListener3}"></activiti:executionListener>
      </extensionElements>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_execution-listener1">
    <bpmndi:BPMNPlane bpmnElement="execution-listener1" id="BPMNPlane_execution-listener1">
      <bpmndi:BPMNShape bpmnElement="start-el1" id="BPMNShape_start-el1">
        <omgdc:Bounds height="30.0" width="30.0" x="195.0" y="210.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-065D83B9-2D5A-4770-A1E8-A1D0A154DD86" id="BPMNShape_sid-065D83B9-2D5A-4770-A1E8-A1D0A154DD86">
        <omgdc:Bounds height="80.0" width="100.0" x="330.0" y="185.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-C8D80560-62C9-44CE-AE7A-65235F11B7F6" id="BPMNShape_sid-C8D80560-62C9-44CE-AE7A-65235F11B7F6">
        <omgdc:Bounds height="28.0" width="28.0" x="690.0" y="211.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-C1F4513F-24AD-44A3-8596-B51E2815D604" id="BPMNShape_sid-C1F4513F-24AD-44A3-8596-B51E2815D604">
        <omgdc:Bounds height="80.0" width="100.0" x="510.0" y="185.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-FF78808D-D503-4B50-9CB8-14079609F480" id="BPMNEdge_sid-FF78808D-D503-4B50-9CB8-14079609F480">
        <omgdi:waypoint x="610.0" y="225.0"></omgdi:waypoint>
        <omgdi:waypoint x="690.0" y="225.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-157E09A5-8D4C-4D96-B938-EFC3863CE682" id="BPMNEdge_sid-157E09A5-8D4C-4D96-B938-EFC3863CE682">
        <omgdi:waypoint x="225.0" y="225.0"></omgdi:waypoint>
        <omgdi:waypoint x="330.0" y="225.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-372284A1-CE05-4FCA-97C3-3DFB49B55CE6" id="BPMNEdge_sid-372284A1-CE05-4FCA-97C3-3DFB49B55CE6">
        <omgdi:waypoint x="430.0" y="225.0"></omgdi:waypoint>
        <omgdi:waypoint x="510.0" y="225.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

对应的监听器的处理类:

代码语言:javascript
复制
/**
 * 执行监听器
 *   需要实现 ExecutionListener 接口
 */
public class ExecutionListener1 implements ExecutionListener {

    @Setter
    private Expression msg1;
    @Setter
    private Expression msg2;

    @Override
    public void notify(DelegateExecution execution) {
        System.out.println("------ExecutionListener1  开始-------------");
        FlowElement currentFlowElement = execution.getCurrentFlowElement();
        System.out.println("currentFlowElement.getName() = " + currentFlowElement.getName());
        String currentActivityId = execution.getCurrentActivityId();
        System.out.println("currentActivityId = " + currentActivityId);
        String eventName = execution.getEventName();
        System.out.println("eventName = " + eventName);
        System.out.println(msg1.getValue(execution));
        System.out.println(msg2.getValue(execution));
        System.out.println("------ExecutionListener1  结束-------------");
    }
}
代码语言:javascript
复制
@Component
public class ExecutionListener2 {



    public void test1(DelegateExecution execution){
        System.out.println("------ExecutionListener2  开始-------------");
        FlowElement currentFlowElement = execution.getCurrentFlowElement();
        System.out.println("currentFlowElement.getName() = " + currentFlowElement.getName());
        String currentActivityId = execution.getCurrentActivityId();
        System.out.println("currentActivityId = " + currentActivityId);
        String eventName = execution.getEventName();
        System.out.println("eventName = " + eventName);
        System.out.println("------ExecutionListener2  结束-------------");
    }
}
代码语言:javascript
复制
@Component
public class ExecutionListener3 implements ExecutionListener {

    @Override
    public void notify(DelegateExecution execution) {
        System.out.println("------ExecutionListener3  开始-------------");
        FlowElement currentFlowElement = execution.getCurrentFlowElement();
        System.out.println("currentFlowElement.getName() = " + currentFlowElement.getName());
        String currentActivityId = execution.getCurrentActivityId();
        System.out.println("currentActivityId = " + currentActivityId);
        String eventName = execution.getEventName();
        System.out.println("eventName = " + eventName);
        System.out.println("------ExecutionListener3  结束-------------");
    }
}

2.任务监听器

任务监听器(Task Listener)是Activiti7中的一个重要概念,用于在任务生命周期中执行特定的操作。任务监听器可以在任务创建任务分配任务完成等事件发生时触发,从而执行相应的逻辑。

 任务监听器可以用于执行各种操作,例如记录任务日志发送通知更新任务状态等。通过在任务监听器中编写逻辑,可以实现对任务生命周期的全面控制和管理。

  任务监听器只能在用户任务节点上配置。可被任务监听器捕获的任务相关事件类型包括以下几种。

  • create:任务创建事件,发生在任务创建后,所有属性被设置时。
  • assignment:任务指派事件,发生在将任务指派给某人时。需要注意的是,该事件在任务创建事件前执行。
  • complete:任务完成事件,发生在任务完成时,即任务数据从执行数据表删除之前。
  • delete:任务删除事件,发生在任务完成时,即任务数据从执行数据表删除之前。

具体的案例讲解:

我们可以通过3中方式来配置任务监听器:

分别是:

  • class属性配置
  • expression属性配置
  • delegateExpression属性配置

我们分别定义这三种类型的Class,分别如下:

代码语言:javascript
复制
public class MyTaskListener1 implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println("MyTaskListener1-----------开始了");
        String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
        System.out.println("taskDefinitionKey = " + taskDefinitionKey);
        String eventName = delegateTask.getEventName();
        System.out.println("eventName = " + eventName);
        System.out.println("MyTaskListener1-----------结束了");
    }
}

@Component
public class MyTaskListener2 {

    public void test1(DelegateTask delegateTask){
        System.out.println("MyTaskListener2-----------开始了");
        String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
        System.out.println("taskDefinitionKey = " + taskDefinitionKey);
        String eventName = delegateTask.getEventName();
        System.out.println("eventName = " + eventName);
        System.out.println("MyTaskListener2-----------结束了");
    }
}

@Component
public class MyTaskListener3 implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println("MyTaskListener3-----------开始了");
        String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
        System.out.println("taskDefinitionKey = " + taskDefinitionKey);
        String eventName = delegateTask.getEventName();
        System.out.println("eventName = " + eventName);
        System.out.println("MyTaskListener3-----------结束了");
    }
}

然后再做相关的配置了

我们在一个用户任务上配置了4个TaskListener.然后部署运行看看具体的效果,启动流程的时候触发了assignmentcreate事件,而且审批人指派是在前面执行的

代码语言:javascript
复制
MyTaskListener2-----------开始了
taskDefinitionKey = sid-4449755D-AC66-41B5-AC4E-68012BE95880
eventName = assignment
MyTaskListener2-----------结束了
MyTaskListener1-----------开始了
taskDefinitionKey = sid-4449755D-AC66-41B5-AC4E-68012BE95880
eventName = create
MyTaskListener1-----------结束了

然后做用户节点的审批操作,completedelete事件执行了。

代码语言:javascript
复制
MyTaskListener3-----------开始了
taskDefinitionKey = sid-4449755D-AC66-41B5-AC4E-68012BE95880
eventName = complete
MyTaskListener3-----------结束了
MyTaskListener1-----------开始了
taskDefinitionKey = sid-4449755D-AC66-41B5-AC4E-68012BE95880
eventName = delete
MyTaskListener1-----------结束了

完整的流程图信息:

代码语言:javascript
复制
<?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/processdef">
  <process id="test111" name="test111" isExecutable="true">
    <documentation>test111</documentation>
    <startEvent id="startEvent1"></startEvent>
    <userTask id="sid-4449755D-AC66-41B5-AC4E-68012BE95880" name="用户任务" activiti:assignee="${user1}">
      <extensionElements>
        <activiti:taskListener event="create" class="com.boge.activiti.listener.MyTaskListener1"></activiti:taskListener>
        <activiti:taskListener event="assignment" expression="${myTaskListener2.test1(task)}"></activiti:taskListener>
        <activiti:taskListener event="complete" delegateExpression="${myTaskListener3}"></activiti:taskListener>
        <activiti:taskListener event="delete" class="com.boge.activiti.listener.MyTaskListener1"></activiti:taskListener>
        <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>
    <sequenceFlow id="sid-07C5D7FE-48DA-4A7E-9F96-A716EB4DC825" sourceRef="startEvent1" targetRef="sid-4449755D-AC66-41B5-AC4E-68012BE95880"></sequenceFlow>
    <endEvent id="sid-3DB05158-BBE1-44FC-902B-368FBD3C5E71"></endEvent>
    <sequenceFlow id="sid-257B3F54-79C6-41A3-9CE3-103A33697253" sourceRef="sid-4449755D-AC66-41B5-AC4E-68012BE95880" targetRef="sid-3DB05158-BBE1-44FC-902B-368FBD3C5E71"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_test111">
    <bpmndi:BPMNPlane bpmnElement="test111" id="BPMNPlane_test111">
      <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
        <omgdc:Bounds height="30.0" width="30.0" x="300.0" y="160.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-4449755D-AC66-41B5-AC4E-68012BE95880" id="BPMNShape_sid-4449755D-AC66-41B5-AC4E-68012BE95880">
        <omgdc:Bounds height="80.0" width="100.0" x="375.0" y="135.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-3DB05158-BBE1-44FC-902B-368FBD3C5E71" id="BPMNShape_sid-3DB05158-BBE1-44FC-902B-368FBD3C5E71">
        <omgdc:Bounds height="28.0" width="28.0" x="520.0" y="161.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-257B3F54-79C6-41A3-9CE3-103A33697253" id="BPMNEdge_sid-257B3F54-79C6-41A3-9CE3-103A33697253">
        <omgdi:waypoint x="475.0" y="175.0"></omgdi:waypoint>
        <omgdi:waypoint x="520.0" y="175.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-07C5D7FE-48DA-4A7E-9F96-A716EB4DC825" id="BPMNEdge_sid-07C5D7FE-48DA-4A7E-9F96-A716EB4DC825">
        <omgdi:waypoint x="330.0" y="175.0"></omgdi:waypoint>
        <omgdi:waypoint x="375.0" y="175.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

3.全局事件监听器

  咱们上面详细介绍了执行监听器任务监听器,他们可以捕获流程在运转过程中产生的相关事件,但是是需要给特定的流程和对应的节点来绑定相关的监听器,有特殊性在这里。在Activiti中还给我们提供了全局事件监听器,它是引擎范围的事件监听器,可以捕获所有的Activiti事件。

3.1 事件监听器的实现

  首先我们来看下针对事件监听器的实现类如何来定义。具体的定义如下,只需实现ActivitiEventListener的接口即可。

代码语言:javascript
复制
public class MyGlobalEventListener implements ActivitiEventListener {

    /**
     * 事件触发执行的方法
     * @param event
     */
    @Override
    public void onEvent(ActivitiEvent event) {
        System.out.println("---全局事件监听器---"+event.getType().toString());
        if (event instanceof TaskRuntimeEvent) {
            TaskRuntimeEvent taskEvent = (TaskRuntimeEvent) event;
            if (event instanceof TaskCreatedEventImpl) {
                // 处理任务创建事件
                System.out.println("Task created: " + taskEvent);
            } else if (event instanceof TaskAssignedEvent) {
                // 处理任务分配事件
                System.out.println("Task assigned: " + taskEvent);
            } else if (event instanceof TaskCompletedEvent) {
                // 处理任务完成事件
                System.out.println("Task completed: " + taskEvent);
            } else if (event instanceof TaskCancelledEvent) {
                // 处理任务取消事件
                System.out.println("Task cancelled: " + taskEvent);
            } else if (event instanceof TaskSuspendedEvent) {
                // 处理任务挂起事件
                System.out.println("Task suspended: " + taskEvent);
            }
        }
    }

    /**
     * 上面的 onEvent 方法抛出异常的后续处理动作
     * @return
     *    false :表示忽略onEvent()方法方法中抛出的异常
     *    true :表示onEvent()方法中抛出的异常继续向上传播,导致当前操作失败
     */
    @Override
    public boolean isFailOnException() {
        return false;
    }
}

在自定义的监听器实现类中我们需要重写如下的两个方法:

  • onEvent:事件触发执行的方法
  • isFailOnException:上面的 onEvent 方法抛出异常的后续处理动作,false :表示忽略onEvent()方法方法中抛出的异常,true :表示onEvent()方法中抛出的异常继续向上传播,导致当前操作失败

3.2 配置事件监听器

  全局监听器的配置有三种方式在工作流引擎配置文件中配置在流程定义文件中配置在代码中调用API动态添加

在工作流引擎配置文件中配置

  我们可以在Activiti7的配置文件中来注册我们上面定义的事件监听器

代码语言:javascript
复制
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti7?nullCatalogMeansCurrent=true" />
    <property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" />
    <property name="jdbcUsername" value="root" />
    <property name="jdbcPassword" value="123456" />
    <property name="databaseSchemaUpdate" value="true" />
    <property name="asyncExecutorActivate" value="true" />
    <property name="mailServerHost" value="mail.my-corp.com" />
    <property name="mailServerPort" value="5025" />
    <property name="eventListeners">
        <list>
            <bean class="com.boge.activiti.listener.MyGlobalEventListener"></bean>
        </list>
    </property>
</bean>

上面我们通过eventListeners这个属性来配置全局的事件监听器,他会监听所有的事件,如果我们想要监听特定的事件,可以通过typedEventListeners这个属性来配置

代码语言:javascript
复制
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti7?nullCatalogMeansCurrent=true" />
    <property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" />
    <property name="jdbcUsername" value="root" />
    <property name="jdbcPassword" value="123456" />
    <property name="databaseSchemaUpdate" value="true" />
    <property name="asyncExecutorActivate" value="true" />
    <property name="mailServerHost" value="mail.my-corp.com" />
    <property name="mailServerPort" value="5025" />
    <property name="typedEventListeners">
        <map>
            <entry key="TASK_CREATED,TASK_COMPLETED">
                <list>
                    <bean class="com.boge.activiti.listener.MyGlobalEventListener"></bean>
                </list>
            </entry>
        </map>
    </property>
</bean>

上面的这个配置就只监听TASK_CREATEDTASK_COMPLETED事件,注意多个事件类型通过,连接。当然我们现在都是在SpringBoot项目中来做项目开发。这块我们的配置需要在配置类中完成。具体如下:

代码语言:javascript
复制
@Configuration
public class Activiti7Config {

    @Autowired
    SpringProcessEngineConfiguration config;

    @PostConstruct
    public void springProcessEngineConfiguration() {
        // 设置自定义的全局事件监听器
        config.setEventListeners(Collections.singletonList(new MyGlobalEventListener()));
    }
}

指派具体的事件类型

代码语言:javascript
复制
@Configuration
public class Activiti7Config {

    @Autowired
    SpringProcessEngineConfiguration config;

    @PostConstruct
    public void springProcessEngineConfiguration() {
        // 设置自定义的全局事件监听器
        Map<String, List<ActivitiEventListener>> map = new HashMap<>();
        map.put("TASK_CREATED", Arrays.asList(new MyGlobalEventListener()));
        config.setTypedEventListeners(map);
    }
}

然后我们可以启动前面案例中部署的任务监听器的流程。先看没有指定具体事件类型的日志输出

代码语言:javascript
复制
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---HISTORIC_PROCESS_INSTANCE_CREATED
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---VARIABLE_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---PROCESS_STARTED
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---HISTORIC_ACTIVITY_INSTANCE_CREATED
---全局事件监听器---ACTIVITY_STARTED
---全局事件监听器---HISTORIC_ACTIVITY_INSTANCE_ENDED
---全局事件监听器---ACTIVITY_COMPLETED
---全局事件监听器---SEQUENCEFLOW_TAKEN
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---HISTORIC_ACTIVITY_INSTANCE_CREATED
---全局事件监听器---ACTIVITY_STARTED
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
---全局事件监听器---VARIABLE_CREATED
MyTaskListener2-----------开始了
taskDefinitionKey = sid-4449755D-AC66-41B5-AC4E-68012BE95880
eventName = assignment
MyTaskListener2-----------结束了
---全局事件监听器---ENTITY_CREATED
---全局事件监听器---ENTITY_INITIALIZED
MyTaskListener1-----------开始了
taskDefinitionKey = sid-4449755D-AC66-41B5-AC4E-68012BE95880
eventName = create
MyTaskListener1-----------结束了
---全局事件监听器---TASK_CREATED
---全局事件监听器---TASK_ASSIGNED

然后是特定事件类型的全局监听器的执行,日志输入如下:

代码语言:javascript
复制
MyTaskListener2-----------开始了
taskDefinitionKey = sid-4449755D-AC66-41B5-AC4E-68012BE95880
eventName = assignment
MyTaskListener2-----------结束了
MyTaskListener1-----------开始了
taskDefinitionKey = sid-4449755D-AC66-41B5-AC4E-68012BE95880
eventName = create
MyTaskListener1-----------结束了
---全局事件监听器---TASK_CREATED

通过流程定义文件配置事件监听器

  当然我们还可以在流程定义中配置事件监听器,不过这种方式配置的事件监听器只能监听于该流程相关的事件以及该流程定义上发起的所有流程实例的事件,具体如下:

  在设计器中点击空白地方有个Event Listeners。可以通过这个功能来设置。但是通过流程设计器在这块配置的时候不是很灵活。我们可以基于BPMN的规范直接在流程图的xml中配置,监听器的配置可以使用3中方式来处理。

  • 通过class属性进行全类名定义;
  • 通过delegateExpression属性引用实现了监听器接口的表达式;
  • 使用throwEvent属性及其额外属性指定抛出的BPMN事件类型。
代码语言:javascript
复制
<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/processdef">
  <process id="test111" name="test111" isExecutable="true">
    <documentation>test111</documentation>
    <extensionElements>
      <!-- 通过class属性来配置事件监听器 -->
      <activiti:eventListener class="com.boge.activiti.listener.MyGlobalEventListener" entityType="task">		
      </activiti:eventListener>
      <activiti:eventListener  delegateExpression="${myGlobalEventListener2}"
                              ></activiti:eventListener>
    </extensionElements>
      <!-- .... 省略 -->
    </process>
</definitions>

在流程运转过程中会有相关的各种信号错误消息等抛出的BPMN事件。在全局事件监听器的配置中我们可以在对应的事件触发的情况下向外抛出相关的事件动作。比如:

代码语言:javascript
复制
<extensionElements>
  <!-- 配置抛出的信号事件 -->
  <activiti:eventListener throwEvent="signal" signalName="MySignal1" events="TASK_CREATED"></activiti:eventListener>
</extensionElements>

上面xml中的相关属性的作用:

  • events: TASK_CREATED 表示监听Task的创建事件
  • throwEvent:signal 表示当触发 task的创建事件后会向外抛出信号事件
  • signalName:MySignal1 表示抛出的事件名称

具体的案例为:

在这里throwEvent可以抛出的类型有:

  • signal:普通信号
  • GlobalSignal:全局信号
  • error:错误
  • message:消息

当然这块也可以和我们前面配置的class 一块使用如下:

代码语言:javascript
复制
<extensionElements>
  <!-- 通过class属性来配置事件监听器 -->
  <activiti:eventListener throwEvent="signal" class="com.boge.activiti.listener.MyGlobalEventListener" signalName="signal1" events="TASK_CREATED"></activiti:eventListener>
</extensionElements>

这个流程定义表示的是即会抛出相关的信号。同时也会在events事件发生的时候触发对应的class中的监听器来处理。

在代码中调用API动态添加

  前面都是我们需要在启动服务之前就要配置好,非常的不灵活。在流程部署和运行后如果需要添加相关的事件监听器。这时可以通过RuntimeService中提供的addEventListener()方法来实现监听器的注册操作。

注意:流程引擎重启后相关的监听器会消失!!!

3.3 日志监听器

  如果我们需要把全局事件监听器的信息持久化到数据库中。也就是保存在act_evt_log表中。那么我们可以通过设置enableDatabaseEventLogging属性来开启。

代码语言:javascript
复制
@Configuration
public class Activiti7Config {

    @Autowired
    SpringProcessEngineConfiguration config;

    @PostConstruct
    public void springProcessEngineConfiguration() {
        // 设置自定义的全局事件监听器
        config.setEventListeners(Collections.singletonList(new MyGlobalEventListener()));
        // 开启日志监听
        config.setEnableDatabaseEventLogging(true);
    }
}

然后在act_evt_log中会记录相关的信息

当然我们也可以禁用掉全局事件监听器。毕竟这块对性能的影响还是比较大的。

代码语言:javascript
复制
@Configuration
public class Activiti7Config {

    @Autowired
    SpringProcessEngineConfiguration config;

    @PostConstruct
    public void springProcessEngineConfiguration() {
        // 设置自定义的全局事件监听器
        config.setEventListeners(Collections.singletonList(new MyGlobalEventListener()));
        // 禁用 全局事件监听器
        config.setEnableEventDispatcher(false);
    }
}

这块的禁用仅仅是禁用了全局事件监听器,对执行监听器任务监听器是没有影响的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.执行监听器
  • 2.任务监听器
  • 3.全局事件监听器
    • 3.1 事件监听器的实现
      • 3.2 配置事件监听器
        • 3.3 日志监听器
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档