Camunda任务监听器:任务生命周期管理
概述
在业务流程管理(BPM)系统中,任务监听器(TaskListener)是Camunda平台中至关重要的组件,它允许开发者在任务生命周期的关键节点注入自定义逻辑。通过任务监听器,可以实现任务创建、分配、完成、更新、删除和超时等事件的响应处理,为业务流程提供强大的扩展能力。
任务监听器核心概念
任务生命周期事件
Camunda任务监听器支持6种核心事件类型,覆盖了任务从创建到完成的完整生命周期:
| 事件类型 | 常量名称 | 触发时机 |
|---|---|---|
| 创建事件 | EVENTNAME_CREATE | 任务创建时触发 |
| 分配事件 | EVENTNAME_ASSIGNMENT | 任务被分配给用户时触发 |
| 完成事件 | EVENTNAME_COMPLETE | 任务完成时触发 |
| 更新事件 | EVENTNAME_UPDATE | 任务属性更新时触发 |
| 删除事件 | EVENTNAME_DELETE | 任务删除时触发 |
| 超时事件 | EVENTNAME_TIMEOUT | 任务超时时触发 |
核心接口定义
public interface TaskListener {
String EVENTNAME_CREATE = "create";
String EVENTNAME_ASSIGNMENT = "assignment";
String EVENTNAME_COMPLETE = "complete";
String EVENTNAME_UPDATE = "update";
String EVENTNAME_DELETE = "delete";
String EVENTNAME_TIMEOUT = "timeout";
void notify(DelegateTask delegateTask);
}
任务监听器实现方式
1. Java类实现
最常用的实现方式,通过实现TaskListener接口创建自定义监听器:
public class CustomTaskListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
String eventName = delegateTask.getEventName();
switch (eventName) {
case TaskListener.EVENTNAME_CREATE:
handleTaskCreate(delegateTask);
break;
case TaskListener.EVENTNAME_COMPLETE:
handleTaskComplete(delegateTask);
break;
case TaskListener.EVENTNAME_ASSIGNMENT:
handleTaskAssignment(delegateTask);
break;
default:
// 处理其他事件
}
}
private void handleTaskCreate(DelegateTask delegateTask) {
// 任务创建时的业务逻辑
String taskId = delegateTask.getId();
String processInstanceId = delegateTask.getProcessInstanceId();
// 设置任务优先级、截止时间等
delegateTask.setPriority(50);
delegateTask.setDueDate(new Date(System.currentTimeMillis() + 7 * 24 * 60 * 60 * 1000));
// 记录审计日志
System.out.println("任务创建: " + taskId + ", 流程实例: " + processInstanceId);
}
private void handleTaskComplete(DelegateTask delegateTask) {
// 任务完成时的业务逻辑
Map<String, Object> variables = delegateTask.getVariables();
// 更新业务数据
updateBusinessData(variables);
// 发送通知
sendCompletionNotification(delegateTask);
}
}
2. 表达式实现
使用Spring表达式语言(SpEL)或统一表达式语言(UEL)实现简单逻辑:
<userTask id="reviewTask" name="Review Document">
<extensionElements>
<camunda:taskListener event="create" expression="${notificationService.sendTaskCreatedNotification(task)}" />
<camunda:taskListener event="complete" expression="${auditService.logTaskCompletion(task)}" />
</extensionElements>
</userTask>
3. 委托表达式实现
通过委托表达式调用Spring Bean中的方法:
<userTask id="approvalTask" name="Approval Request">
<extensionElements>
<camunda:taskListener event="create" delegateExpression="${taskLifecycleManager}" />
</extensionElements>
</userTask>
对应的Spring Bean配置:
@Component("taskLifecycleManager")
public class TaskLifecycleManager implements TaskListener {
@Autowired
private NotificationService notificationService;
@Autowired
private AuditService auditService;
@Override
public void notify(DelegateTask delegateTask) {
// 实现完整的任务生命周期管理
}
}
DelegateTask接口详解
DelegateTask接口提供了丰富的任务操作方法和属性访问能力:
public interface DelegateTask extends VariableScope, BpmnModelExecutionContext, ProcessEngineServicesAware {
// 获取任务基本信息
String getId();
String getName();
String getDescription();
int getPriority();
// 获取分配信息
String getAssignee();
String getOwner();
Date getCreateTime();
Date getDueDate();
// 获取流程上下文信息
String getProcessInstanceId();
String getProcessDefinitionId();
String getExecutionId();
String getCaseInstanceId();
String getCaseDefinitionId();
// 事件相关信息
String getEventName();
// 任务操作方法
void setAssignee(String assignee);
void setOwner(String owner);
void setPriority(int priority);
void setDueDate(Date dueDate);
// 变量操作
Object getVariable(String variableName);
void setVariable(String variableName, Object value);
Map<String, Object> getVariables();
}
实战应用场景
场景1:自动任务分配
public class AutoAssignmentListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
if (TaskListener.EVENTNAME_CREATE.equals(delegateTask.getEventName())) {
String taskName = delegateTask.getName();
String department = (String) delegateTask.getVariable("department");
// 根据业务规则自动分配任务
String assignee = determineAssignee(taskName, department);
delegateTask.setAssignee(assignee);
// 记录分配日志
logAssignment(delegateTask.getId(), assignee);
}
}
private String determineAssignee(String taskName, String department) {
// 实现复杂的分配逻辑
if ("财务审批".equals(taskName) && "财务部".equals(department)) {
return "finance_manager";
} else if ("技术评审".equals(taskName)) {
return "tech_lead";
}
return "default_user";
}
}
场景2:任务超时处理
public class TimeoutHandlerListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
if (TaskListener.EVENTNAME_TIMEOUT.equals(delegateTask.getEventName())) {
String taskId = delegateTask.getId();
String assignee = delegateTask.getAssignee();
// 发送超时提醒
sendTimeoutNotification(assignee, taskId);
// 自动升级处理
escalateTask(delegateTask);
// 记录超时事件
logTimeoutEvent(taskId);
}
}
}
场景3:任务完成后的业务处理
public class PostCompletionProcessor implements TaskListener {
@Autowired
private BusinessService businessService;
@Autowired
private NotificationService notificationService;
@Override
public void notify(DelegateTask delegateTask) {
if (TaskListener.EVENTNAME_COMPLETE.equals(delegateTask.getEventName())) {
// 获取任务结果
String outcome = (String) delegateTask.getVariable("outcome");
Map<String, Object> variables = delegateTask.getVariables();
// 更新业务数据
businessService.updateBusinessData(
delegateTask.getProcessInstanceId(),
outcome,
variables
);
// 发送完成通知
notificationService.sendCompletionNotification(
delegateTask.getAssignee(),
delegateTask.getName(),
outcome
);
// 生成审计记录
createAuditLog(delegateTask, outcome);
}
}
}
最佳实践和注意事项
1. 性能优化
public class EfficientTaskListener implements TaskListener {
// 使用缓存提高性能
private static final Map<String, String> TASK_ASSIGNMENT_RULES = new ConcurrentHashMap<>();
static {
TASK_ASSIGNMENT_RULES.put("财务审批-财务部", "finance_manager");
TASK_ASSIGNMENT_RULES.put("技术评审", "tech_lead");
}
@Override
public void notify(DelegateTask delegateTask) {
// 避免在监听器中执行耗时操作
if (isTimeSensitiveOperation()) {
// 使用异步处理
CompletableFuture.runAsync(() -> processAsync(delegateTask));
} else {
processSync(delegateTask);
}
}
}
2. 错误处理
public class RobustTaskListener implements TaskListener {
private static final Logger logger = LoggerFactory.getLogger(RobustTaskListener.class);
@Override
public void notify(DelegateTask delegateTask) {
try {
// 主业务逻辑
processTaskEvent(delegateTask);
} catch (Exception e) {
// 优雅的错误处理
logger.error("任务监听器执行失败: {}", delegateTask.getId(), e);
// 记录错误但不中断流程
recordError(delegateTask, e);
// 发送错误通知
sendErrorNotification(delegateTask, e);
}
}
}
3. 事务管理
高级特性
1. 监听器执行顺序控制
<userTask id="complexTask" name="Complex Processing">
<extensionElements>
<!-- 内置监听器优先执行 -->
<camunda:taskListener event="create" class="org.camunda.bpm.engine.impl.bpmn.behavior.UserTaskActivityBehavior$1" />
<!-- 自定义业务监听器 -->
<camunda:taskListener event="create" class="com.example.ValidationListener" />
<camunda:taskListener event="create" class="com.example.AssignmentListener" />
<camunda:taskListener event="create" class="com.example.NotificationListener" />
</extensionElements>
</userTask>
2. 条件监听器
public class ConditionalTaskListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
// 根据条件执行不同的逻辑
String processDefinitionKey = delegateTask.getProcessDefinitionId().split(":")[0];
if ("invoice-approval".equals(processDefinitionKey)) {
handleInvoiceApproval(delegateTask);
} else if ("vacation-request".equals(processDefinitionKey)) {
handleVacationRequest(delegateTask);
} else {
handleDefaultScenario(delegateTask);
}
}
}
总结
Camunda任务监听器提供了强大的任务生命周期管理能力,通过6种核心事件类型覆盖了任务的完整生命周期。开发者可以通过Java类、表达式、委托表达式等多种方式实现监听器逻辑,满足不同复杂度的业务需求。
关键要点:
- 事件驱动:基于任务生命周期事件触发相应逻辑
- 灵活实现:支持多种实现方式,从简单表达式到复杂Java类
- 完整上下文:通过DelegateTask接口访问完整的任务和流程信息
- 错误恢复:完善的错误处理机制确保流程稳定性
- 性能优化:支持异步处理和性能优化策略
通过合理使用任务监听器,可以构建出高度可定制、健壮可靠的业务流程管理系统,满足企业级应用的复杂需求。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



