activiti學習10任務監聽器的使用
activiti學習10任務監聽器的使用
activiti提供了任務監聽器,允許在任務執行的過程中執行特定的java程式或者表示式,目前任務監聽器只能在user task中使用。在流程定義檔案中通過為bpmn 2.0 的元素extensionElements新增activiti:taskListener
子元素來定義一個任務監聽。任務監聽器不是bpmn規範的內容,是activiti對其的擴充套件。
一、使用class指定監聽器
在流程檔案中,可以使用activiti:taskListener
元素的class屬性來指定監聽器的java類,使用這種方式,監聽器類必須實現org.activiti.engine.delegate.TaskListener
自定義監聽器類
public class MyListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
System.out.println("自定義任務監聽器執行了");
}
}
其中DelegateTask是一個介面,通過該介面可以操作當前的user task物件
在流程定義檔案中用class屬性來指定該監聽器
<userTask id="sid-03CF0A31-4FD4-4F04-90BA-72785636060C" name="用class屬性指定任務監聽器"> <extensionElements> <activiti:taskListener event="create" class="com.lyy.activiti_listener.MyListener"> </activiti:taskListener> </extensionElements> </userTask>
這樣就通過class屬性給一個使用者任務指定了一個任務監聽器,當流程執行到這個使用者任務時,該任務監聽器就會被執行。
二、使用expression來指定監聽器
使用activiti:taskListener
元素的expression屬性來指定監聽器
通過juel表示式指定某個java類中的公共方法,這個java類需要實現序列化介面,把它的物件放在流程變數中,如果整合了spring,也可以是spring容器中的bean
<userTask id="sid-E3A5B9D7-1985-4A8B-987F-F9B1589AA27A" name="使用expression指定監聽器"> <extensionElements> <activiti:taskListener event="create" expression="${myListener.execute(task)}"> </activiti:taskListener> </extensionElements> </userTask>
上面這個使用者任務,使用expression屬性指定了監聽器的juel表示式,表示執行myListener這個物件的execute方法。引數task是DelegateTask型別的,可以用來操作當前任務。下邊是對應的任務監聽器
//@Component("myListener")
public class MyListener2 implements Serializable {
public void execute(DelegateTask delegateTask){
System.out.println("使用表示式來指定監聽器");
}
}
當流程執行到這個任務時,可以在流程變數中放一個名為myListener的變數,值是自定義監聽器的物件。
Map<String,Object> map=new HashMap<>();
map.put("myListener",new MyListener2());
runtimeService.startProcessInstanceByKey("taskListener_study2",map);
也可以把上邊的這個監聽器加入spring容器中,指定bean名稱為myListener
這樣當這個任務建立後就會執行監聽器程式碼。
三、使用delegateExpression指定監聽器
也可以使用delegateExpression 配合juel表示式指定任務監聽器,對應的監聽器類要實現TaskListener和序列化介面。假如juel表示式配置${myTaskListener3}
,activiti會從流程中查詢名稱為myTaskListener3的流程變數,並執行其notify方法。
監聽器的程式碼如下
public class MyListener3 implements TaskListener,Serializable {
@Override
public void notify(DelegateTask delegateTask) {
System.out.println("使用delegateExpression來指定監聽器");
}
}
在流程定義檔案中配置監聽器
<userTask id="sid-091EB299-76A8-4DBD-A1A5-50F0E25B97DA" name="使用delegateExpression指定監聽器">
<extensionElements>
<activiti:taskListener event="create" delegateExpression="${myTaskListener3}">
</activiti:taskListener>
</extensionElements>
</userTask>
在流程到達該任務節點時,就會從流程變數中獲取myTaskListener3,並執行notify方法
四、監聽器的觸發
任務監聽器會在任務的不同事件中被觸發,包括任務建立(create),任務完成(complete),指定代理人(assignment),通過activiti:taskListener
的event屬性來指定監聽器的觸發事件。
像上邊的幾個例子,都是使用的create事件。
需要注意的是,一個使用者任務可以配置多個監聽器,這種情況下assignment事件的監聽器會比create先執行,因為指定任務代理人屬於任務建立過程的一部分,create事件只有當任務的所有資料都寫入到資料庫後才會觸發。
五、總結
對三種指定監聽器的方式進行一個比較,
(1) class方式,監聽器只需要實現TaskListener介面,不需要在流程變數中加入監聽器類的物件
(2)expression方式,監聽器可以是一個普通的java類,但要實現序列化介面,需要在流程變數中加入監聽器類的物件,或者加入spring容器中
(3)delegateExpression,監聽器要同時實現TaskListener和序列化介面,需要在流程變數中加入監聽器類的物件