1. 程式人生 > 實用技巧 >activiti學習10任務監聽器的使用

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和序列化介面,需要在流程變數中加入監聽器類的物件