執行監聽器與任務監聽器的基本使用


本文介紹執行監聽器與任務監聽器的基本原理和使用方法。當流程途徑連線或者節點的時候,會觸發對應的事件類型。執行監聽器與任務監聽器在生產中經常會用在幾個方面:

  • 動態分配節點處理人。通過前一個節點設置的變量,在運行到下一個節點時設置對應的處理人;
  • 當流程運行到某個節點時,發送郵件或短信給待辦用戶;
  • 統計流程處理時長,是否超時等;
  • 業務層面數據處理。

任務監聽器顧名思義是監聽任務的。任務監聽器的生命周期如下圖所示,會經歷assignment、create、complete、delete。當流程引擎觸發這四種事件類型時,對應的任務監聽器會捕獲其事件類型,再按照監聽器的處理邏輯進行處理。

 

 

 

執行監聽器則監聽流程的所有節點和連線。主要有start、end、take事件。其中節點有start、end兩種事件,而連線則有take事件。下圖是執行監聽器的生命周期:

 

 

 

接下來通過代碼去演示監聽器效果。 首先我們創建一個執行監聽器的類:

package listener;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

public class MyExecutionListener implements ExecutionListener {

public void notify(DelegateExecution execution) throws Exception {
System.out.println("============executionListener start============");
String eventName = execution.getEventName();
String currentActivitiId = execution.getCurrentActivityId();
System.out.println("事件名稱:" + eventName);
System.out.println("ActivitiId:" + currentActivitiId);
System.out.println("============executionListener end============");
}
}

 


自定義執行監聽器需要實現ExecutionListener接口,並且實現notify方法。這里我們打印對應的事件和活動節點id

接下來創建一個自定任務監聽器:

package listener;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

public class MyTaskListener implements TaskListener{

public void notify(DelegateTask delegateTask) {
System.out.println("============TaskListener start============");
String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
String eventName = delegateTask.getEventName();
System.out.println("事件名稱:" + eventName);
System.out.println("taskDefinitionKey:" + taskDefinitionKey);
System.out.println("============TaskListener end============");
}
}

 


自定義任務監聽器需要實現TaskListener接口,並且實現notify方法。這里我們打印對應的事件和任務節點鍵值(即bpmn圖里userTask的id)。

之后新建一個bpmn圖:

<?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/test">
<process id="listenerBpmProcess" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<userTask id="usertask1" name="myTask1" activiti:assignee="張三">
<extensionElements>
<activiti:executionListener event="start" class="listener.MyExecutionListener"></activiti:executionListener>
<activiti:executionListener event="end" class="listener.MyExecutionListener"></activiti:executionListener>
<activiti:taskListener event="all" class="listener.MyTaskListener"></activiti:taskListener>
</extensionElements>
</userTask>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_listenerBpmProcess">
<bpmndi:BPMNPlane bpmnElement="listenerBpmProcess" id="BPMNPlane_listenerBpmProcess">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="41.0" width="35.0" x="505.0" y="40.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="470.0" y="150.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="505.0" y="240.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="522.0" y="81.0"></omgdi:waypoint>
<omgdi:waypoint x="522.0" y="150.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="522.0" y="205.0"></omgdi:waypoint>
<omgdi:waypoint x="522.0" y="240.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

 


這里我們給userTask1添加了執行監聽器和任務監聽器。部署bpmn圖后,我們觀察流程運轉時監聽器的觸發時機和作用,啟動流程:

public void startProcessById() {
RuntimeService runtimeService = pe.getRuntimeService();
ProcessInstance pi = runtimeService.startProcessInstanceById("listenerBpmProcess:1:4");
}

 


流程啟動后,從開始節點運轉到userTask1節點,觀察控制台輸出:

============executionListener start============
事件名稱:start
ActivitiId:usertask1
============executionListener end============
============TaskListener start============
事件名稱:assignment
taskDefinitionKey:usertask1
============TaskListener end============
============TaskListener start============
事件名稱:create
taskDefinitionKey:usertask1
============TaskListener end============


可以看到流程走到userTask1節點時,首先觸發start事件,調用我們自定義的執行監聽器,隨后觸發assignment和create事件,執行自定義任務監聽器的內容。注意這里是先觸發assignment進行人員分配,再觸發create事件,與一般的認知有些差異。

接下來通過taskService的complete方法完成userTask1節點上流程的提交,觀察控制台輸出:

 

============TaskListener start============
事件名稱:complete
taskDefinitionKey:usertask1
============TaskListener end============
============TaskListener start============
事件名稱:delete
taskDefinitionKey:usertask1
============TaskListener end============
============executionListener start============
事件名稱:end
ActivitiId:usertask1
============executionListener end============


可以看到userTask1節點提交的時候,首先觸發complete事件再觸發delete事件,最后觸發end事件。

以上就是執行監聽器與任務監聽器的基本使用方式。實際工程中,由於流程節點十分多,並且流程和業務常常需要進行微調,通常是不會在bpmn圖上逐個節點添加監聽器的,往往是在解析bpmn對象期間利用對象解析器動態添加監聽器。這里涉及的原理比較復雜,留到后面的文章再討論。

到本文為止,講的都是activiti的入門用法,可以順利跑通一個流程,還能在流程運行的途中進行一些監聽和操作。activiti的入門概念不少,但使用並不復雜。

 原文鏈接:https://blog.csdn.net/sadoshi/article/details/104698749/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM