Camunda 服务任务(Service Task)中 External、Java class、Expression、Delegate expression、Connector 这 5 种实现方式的
前置说明
所有配置都在 Camunda Modeler 中完成:选中 Service Task 节点 → 右侧属性面板 → Implementation 下拉框选择对应类型 → 在下方的输入框(如Java Class、Expression等)填写内容。
1. External(外部任务)
填写规则
- Implementation 选
External - 下方 Topic 输入框:填写自定义的外部任务主题名(字符串,无特殊格式,仅需和外部工作器(Worker)的主题名一致)
- 可选:配置 Retry Time Cycle(任务失败后重试规则,如
R3/PT5M表示重试3次,每次间隔5分钟)
示例
- Topic 填写:
leave_approval_check(请假审批校验)、order_payment_process(订单支付处理) - Retry Time Cycle 填写:
R5/PT1M(重试5次,每次间隔1分钟)
适用场景
- 耗时较长的业务逻辑(如调用外部接口、批量处理数据),避免阻塞流程引擎
- 需要分布式部署的任务(多台机器的Worker可消费同一个Topic的任务)
- 代码和流程引擎解耦(Worker可独立部署、扩容)
配套代码(外部Worker示例)
importorg.camunda.bpm.client.ExternalTaskClient;publicclassLeaveApprovalWorker{publicstaticvoidmain(String[] args){// 创建外部任务客户端ExternalTaskClient client =ExternalTaskClient.create().baseUrl("http://localhost:8080/engine-rest")// Camunda REST接口地址.asyncResponseTimeout(10000)// 异步响应超时时间.build();// 订阅Topic(必须和Modeler中填写的Topic一致) client.subscribe("leave_approval_check").lockDuration(60000)// 锁时长(60秒,防止其他Worker重复处理).handler((externalTask, externalTaskService)->{// 1. 获取流程变量String applicant =(String) externalTask.getVariable("applicant");Integer leaveDays =(Integer) externalTask.getVariable("leaveDays");// 2. 执行业务逻辑boolean approve = leaveDays <=3;// 3. 设置输出变量 externalTaskService.complete(externalTask,Map.of("approveResult", approve));}).open();// 启动Worker}}2. Java class(Java类)
填写规则
- Implementation 选
Java class - 下方 Java Class 输入框:填写完整类名(包名+类名),类必须实现
org.camunda.bpm.engine.delegate.JavaDelegate接口 - 要求:该类必须在 Camunda 引擎的类路径下(Spring Boot 项目中需加
@Component或手动注册到Spring容器)
示例
- 完整类名填写:
com.example.camunda.service.LeaveApprovalService - 对应代码类:
packagecom.example.camunda.service;// 包名必须和配置的一致importorg.camunda.bpm.engine.delegate.DelegateExecution;importorg.camunda.bpm.engine.delegate.JavaDelegate;importorg.springframework.stereotype.Component;@Component// 交给Spring管理publicclassLeaveApprovalServiceimplementsJavaDelegate{@Overridepublicvoidexecute(DelegateExecution execution)throwsException{// 业务逻辑}}适用场景
- 简单的同步业务逻辑,代码和流程引擎耦合度可接受
- 不需要灵活调用方法,仅需执行固定的
execute方法
3. Expression(表达式)
填写规则
- Implementation 选
Expression - 下方 Expression 输入框:填写 Spring EL表达式,格式为
${bean名称.方法名(参数1, 参数2,...)}bean名称:Spring容器中的Bean名(默认类名首字母小写,或@Service("自定义名")指定)方法名:Bean中的具体方法名参数:可填流程变量名(直接写变量名)、常量(字符串加引号,数字直接写)
- 可选:Result Variable 输入框:填写变量名,用于接收方法返回值(回写到流程变量)
示例
场景1:调用无参方法
- Expression:
${leaveService.checkDefaultRule()} - 对应代码:
@Service("leaveService")publicclassLeaveService{publicbooleancheckDefaultRule(){returntrue;}}场景2:调用带流程变量参数的方法
- Expression:
${leaveService.checkLeaveLimit(applicant, leaveDays)}applicant、leaveDays是流程变量名,会自动传入方法
- Result Variable:
checkResult(方法返回值会存到这个流程变量中) - 对应代码:
@Service("leaveService")publicclassLeaveService{publicbooleancheckLeaveLimit(String applicant,Integer leaveDays){System.out.println("校验"+ applicant +"的请假天数:"+ leaveDays);return leaveDays <=5;}}场景3:调用带常量+流程变量的方法
- Expression:
${leaveService.calcLeaveDays(leaveDays, "2026-01-20")}leaveDays是流程变量,"2026-01-20"是常量字符串
适用场景
- 需要灵活调用Bean的任意方法(而非固定的
execute方法) - 方法有明确的参数和返回值,需直接映射到流程变量
4. Delegate expression(委托表达式)
填写规则
- Implementation 选
Delegate expression - 下方 Delegate Expression 输入框:填写 Spring EL表达式,格式为
${bean名称}bean名称:Spring容器中的Bean名,该Bean必须实现JavaDelegate或ActivityBehavior接口
- 核心:表达式只指定Bean名,引擎会自动调用该Bean的
execute方法
示例
- Delegate Expression:
${leaveApprovalService} - 对应代码(和Java class的类结构一致,仅配置方式不同):
@Component("leaveApprovalService")// Bean名必须和表达式中的一致publicclassLeaveApprovalServiceimplementsJavaDelegate{@Overridepublicvoidexecute(DelegateExecution execution)throwsException{// 业务逻辑}}适用场景
- 推荐!Spring Boot集成Camunda的首选方式,比Java class更灵活(支持Spring依赖注入)
- 代码复用性高(同一个Bean可被多个服务节点调用)
- 便于单元测试(可通过Spring上下文注入Mock Bean)
5. Connector(连接器)
填写规则
- Implementation 选
Connector - 下方 Connector Id 输入框:填写内置/自定义连接器ID(Camunda内置了部分连接器,如
http-connector、email-connector) - 点击 Edit 按钮:在弹出的面板中配置连接器参数(键值对,不同连接器参数不同)
示例(最常用的HTTP连接器)
步骤1:填写Connector Id
- Connector Id:
http-connector
步骤2:配置参数(Edit面板中)
| 参数名 | 填写值示例 | 说明 |
|---|---|---|
url | https://api.example.com/leave/check | 目标接口地址 |
method | POST | 请求方法(GET/POST等) |
headers | {"Content-Type":"application/json"} | 请求头(JSON格式) |
payload | {"applicant":"${applicant}","leaveDays":${leaveDays}} | 请求体(可嵌入流程变量) |
resultVariable | httpResponse | 响应结果存储的流程变量名 |
适用场景
- 无需编写Java代码,直接调用外部HTTP接口、发送邮件、操作数据库
- 简单的集成场景(如调用第三方API、发送通知)
- 非定制化的通用操作(避免重复编写HTTP调用、邮件发送代码)
注意
- 内置连接器需引入对应依赖(如HTTP连接器需
camunda-connect-http-client) - 复杂的业务逻辑不适合用Connector,仍需用Java代码实现
总结
| 类型 | 填写核心格式 | 核心适用场景 |
|---|---|---|
| External | Topic名(自定义字符串) | 耗时/分布式任务,解耦流程引擎 |
| Java class | 完整类名(包名+类名) | 简单同步任务,固定execute方法 |
| Expression | ${bean名.方法名(参数)} | 灵活调用Bean的任意方法 |
| Delegate expression | ${bean名} | Spring Boot集成首选,依赖注入友好 |
| Connector | 连接器ID + 参数配置 | 无代码调用HTTP/邮件等通用接口 |
核心建议:日常开发优先用 Delegate expression(简单、适配Spring),耗时任务用 External,无代码集成用 Connector,Expression 用于灵活调用特定方法,Java class 仅做兼容使用。