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和序列化接口,需要在流程變量中加入監聽器類的對象