Camunda中的Execution listeners和Task listeners

浪迹天涯的派大星發表於2024-10-24

在Camunda中大多數節點元素都可以設定執行監聽器(Execution listeners),例如事件、順序流、使用者任務、服務任務和閘道器。其中使用者任務除了可以設定執行監聽器,還可以設定獨有的使用者任務監聽器,相比於執行監聽器,使用者任務監聽器可以設定更加細粒度的事件型別。

下面針對執行監聽器和使用者任務監聽器,結合圖片和程式碼進行說明。

1、Execution listeners

執行監聽器支援的Listener type如下,有Java class、Expression、Delegate expression和Script,下面針對這幾種的配置和程式碼實現進行說明

Camunda中的Execution listeners和Task listeners

1.1、Java class

Java class配置完整的包名和類名,並選擇Event type是開始或結束事件型別,對應節點執行前和執行後。

Camunda中的Execution listeners和Task listeners

關鍵點:新增一個java類,實現JavaDelegate介面,並重寫execute方法,利用spring@Component註解注入bean,配置當前類的完整路徑即可。

根據eventName區分是什麼事件,在裡面實現對應的邏輯,程式碼示例如下:

package org.example.executionlistener;

import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.ExecutionListener;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class ExecutionTaskService implements JavaDelegate {

    @Override
    public void execute(DelegateExecution execution) throws Exception {
        String eventName = execution.getEventName();
        String currentActivityName = execution.getCurrentActivityName();
        if (ExecutionListener.EVENTNAME_END.equals(eventName)) {
        } else if (ExecutionListener.EVENTNAME_START.equals(eventName)) {
        } else if (ExecutionListener.EVENTNAME_TAKE.equals(eventName)) {
        }
        log.info("SystemTaskService execute,taskName={},eventName={}", currentActivityName, eventName);
    }
}

1.2 Expression

針對自定義的java類和方法,支援透過表示式的方式配置,配置如下:

Camunda中的Execution listeners和Task listeners

關鍵點:EL表示式不需要實現JavaDelegate介面,直接使用Spring Bean的名稱和方法名稱即可,根據eventName區分是start事件還是end事件,在裡面實現自己的邏輯。

注:camunda內建了一部分上下文引數,可以在表示式中直接使用,文件連結:Expression Language | docs.camunda.org

Camunda中的Execution listeners和Task listeners

程式碼示例如下:

package org.example.executionlistener;

import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;

@Component("expressionExecutionService")
@Slf4j
public class ExpressionService {

    public void expression(DelegateExecution execution) {
        String eventName = execution.getEventName();
        String currentActivityName = execution.getCurrentActivityName();
        log.info("Execution ExpressionService,taskName={},eventName={}", currentActivityName, eventName);
    }

}

1.3 Delegate expression

委託表示式配置如下:

Camunda中的Execution listeners和Task listeners

關鍵點:DelegateExpression和Expression類似,區別在於需要實現JavaDelegate介面,此時只需要傳入bean的名稱即可,不需要指定方法名和引數。

示例程式碼如下:

package org.example.executionlistener;

import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.ExecutionListener;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.springframework.stereotype.Component;

@Component("executionTaskService")
@Slf4j
public class ExecutionTaskService implements JavaDelegate {

    @Override
    public void execute(DelegateExecution execution) throws Exception {
        String eventName = execution.getEventName();
        String currentActivityName = execution.getCurrentActivityName();
        if (ExecutionListener.EVENTNAME_END.equals(eventName)) {
        } else if (ExecutionListener.EVENTNAME_START.equals(eventName)) {
        } else if (ExecutionListener.EVENTNAME_TAKE.equals(eventName)) {
        }
        log.info("SystemTaskService execute,taskName={},eventName={}", currentActivityName, eventName);
    }
}

1.4 Script

camunda支援在執行監聽器中編寫指令碼進行處理,如下可以在Script框中編寫指令碼,沒有使用過,不進行詳細說明,感興趣可以自行研究

Camunda中的Execution listeners和Task listeners

2、Task listeners

任務監聽器是獨屬於使用者任務的,其支援的事件型別和監聽器型別分別如下所示:

Camunda中的Execution listeners和Task listenersCamunda中的Execution listeners和Task listeners

從上面可以看到,與執行監聽器相比,任務監聽器支援的事件型別更加豐富,意味這個可以在使用者任務的各個階段處理我們自定義的邏輯;其監聽器型別和Execution listeners一樣,同樣支援四種方式。

下面給出Java Class和Delegate expression兩種方式的實現。

2.1、Java class

使用者任務監聽器和執行監聽器的Java class配置和程式碼實現類似,區別在於實現的介面不同,eventName的種類更多,示例配置如下所示:

Camunda中的Execution listeners和Task listeners

關鍵點:新增一個java類,實現TaskListener介面,並重寫notify方法,利用spring@Component註解注入bean,最後配置當前類的完整路徑即可。

程式碼示例如下:

package org.example.usertask;

import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.delegate.DelegateTask;
import org.camunda.bpm.engine.delegate.TaskListener;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class JavaClassListener implements TaskListener {

    @Override
    public void notify(DelegateTask delegateTask) {
        String eventName = delegateTask.getEventName();
        String name = delegateTask.getName();
        if (TaskListener.EVENTNAME_CREATE.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_ASSIGNMENT.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_COMPLETE.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_DELETE.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_TIMEOUT.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_UPDATE.equals(eventName)) {
        }
        log.info("UserTaskListener UserTaskListener,userTaskName={},eventName={}", name, eventName);
    }
}

2.2 Delegate expression

其在委託表示式的配置示例如下所示:

關鍵點:只需要實現TaskListener介面,利用spring的@Component註解,傳入設定的Bean的名稱即可。

Camunda中的Execution listeners和Task listeners

程式碼示例如下:

package org.example.usertask;

import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.delegate.DelegateTask;
import org.camunda.bpm.engine.delegate.TaskListener;
import org.springframework.stereotype.Component;

@Component("userTaskListener")
@Slf4j
public class UserTaskListener implements TaskListener {

    @Override
    public void notify(DelegateTask delegateTask) {
        String eventName = delegateTask.getEventName();
        String name = delegateTask.getName();
        if (TaskListener.EVENTNAME_CREATE.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_ASSIGNMENT.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_COMPLETE.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_DELETE.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_TIMEOUT.equals(eventName)) {
        } else if (TaskListener.EVENTNAME_UPDATE.equals(eventName)) {
        }
        log.info("UserTaskListener UserTaskListener,userTaskName={},eventName={}", name, eventName);
    }
}

2.3 Expression

使用者任務監聽器的表示式寫法和上面執行監聽器的表示式寫法一樣,區別在於其用到的上下文引數不一樣,執行監聽器用到的方法引數是DelegateExecution execution,使用者任務監聽器用到的方法引數是DelegateTask task,詳細見上面的Camunda內建的上下文引數,其示例配置如下:

Camunda中的Execution listeners和Task listeners

示例程式碼如下:

package org.example.usertask;

import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.delegate.DelegateTask;
import org.springframework.stereotype.Component;

@Component("expressionService")
@Slf4j
public class ExpressionService {
    public void expression(DelegateTask task) {
        String eventName = task.getEventName();
        String name = task.getName();
        //根據eventName來進行自定義邏輯
        log.info("ExpressionService expression,userTaskName={},eventName={}", name, eventName);
    }
}

2.4 Script

和上面的執行監聽器類似,不再贅述。

相關文章