Camunda中的Execution listeners和Task listeners
在Camunda中大多数节点元素都可以设置执行监听器(Execution listeners),例如事件、顺序流、用户任务、服务任务和网关。其中用户任务除了可以设置执行监听器,还可以设置独有的用户任务监听器,相比于执行监听器,用户任务监听器可以设置更加细粒度的事件类型。
下面针对执行监听器和用户任务监听器,结合图片和代码进行说明。
1、Execution listeners
执行监听器支持的Listener type如下,有Java class、Expression、Delegate expression和Script,下面针对这几种的配置和代码实现进行说明
1.1、Java class
Java class配置完整的包名和类名,并选择Event type是开始或结束事件类型,对应节点执行前和执行后。
关键点:新增一个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类和方法,支持通过表达式的方式配置,配置如下:
关键点:EL表达式不需要实现JavaDelegate接口,直接使用Spring Bean的名称和方法名称即可,根据eventName区分是start事件还是end事件,在里面实现自己的逻辑。
注:camunda内置了一部分上下文参数,可以在表达式中直接使用,文档链接:Expression Language | docs.camunda.org
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
委托表达式配置如下:
关键点: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框中编写脚本,没有使用过,不进行详细说明,感兴趣可以自行研究
2、Task listeners
任务监听器是独属于用户任务的,其支持的事件类型和监听器类型分别如下所示:
从上面可以看到,与执行监听器相比,任务监听器支持的事件类型更加丰富,意味这个可以在用户任务的各个阶段处理我们自定义的逻辑;其监听器类型和Execution listeners一样,同样支持四种方式。
2.1、Java class
用户任务监听器和执行监听器的Java class配置和代码实现类似,区别在于实现的接口不同,eventName的种类更多,示例配置如下所示:
关键点:新增一个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的名称即可。
代码示例如下:
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内置的上下文参数,其示例配置如下:
示例代码如下:
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
和上面的执行监听器类似,不再赘述。