# 服务任务
服务任务不同于用户任务,不需要进行人工处理,是一种自动化的任务。当流程流转到服务任务时,会自动执行服务任务中边界的Java程序。 Java程序执行完毕之后,流程将沿着服务任务外出顺序流继续流转。
# 图形标记
右上角的标识是用来区分任务类型,可以通过小扳手按需调整,右上角齿轮形状即表示服务任务。
# XML内容
<bpmn:serviceTask id="Activity_0kkx1gi" name="服务任务" />
# 调用逻辑
有3种方法来声明调用逻辑,用于指定服务任务所调用的Java类或Spring容器中的Bean
- 通过activiti:class属性指定一个Java类
<bpmn:serviceTask id="Activity_0kkx1gi" name="服务任务" class="com.xx.xx.MyJavaDelegate" />
对应的Java代码
public class MyJavaDelegate implement JavaDelegate{
@Override
public void execute(DelegateExecution execution){
//在这里编写业务代码
}
}
通过这种方式,当流程流转到服务任务时,流程引擎将创建一个实例,该对象会复用,所有流程实例将共享相同的实例。
如果Java类中使用了成员变量,必须保障线程安全。
- 通过delegateExpression使用委托表达式指定
<bpmn:serviceTask id="Activity_0kkx1gi" name="服务任务" delegateExpression="${delegatBean}" />
delegateBean是一个实现JavaDelegate接口的Bean
- 通过expression属性使用UEL表达式指定
//不带参数
<bpmn:serviceTask id="Activity_0kkx1gi" name="服务任务" expression="${businessBean.count()}" />
//带参数
<bpmn:serviceTask id="Activity_0kkx1gi" name="服务任务" expression="${businessBean.count(execution, money)}" />
//相当于调用getTotal()方法
<bpmn:serviceTask id="Activity_0kkx1gi" name="服务任务" expression="${businessBean.total}" />
这种方式在表达式调用前需要将其初始化到流程变量中,或者注册到Spring容器中。不需要实现JavaDelegate,表达式必须指定方法名和属性名
# 异常处理
使用服务任务,当执行自定义逻辑时,经常需要捕获对应的业务异常,并在流程中进行处理。有以下几种方式
- 抛出Bpmn Errors
public class ThrowBpmnErrorDelegate implement JavaDelegate{
@Override
public void execute(DelegateExecution execution){
try{
//自定义逻辑
}catch (Exception e){
throw new BpmnError("Business Exception")
}
}
}
这种方式只适用于业务异常,需要通过定义错误边界事件或错误事件子流程进行处理。技术上的应使用其他异常类型,通常不在流程内部处理。
- 指定异常顺序流
在异常发生时,如果服务任务是通过class指定Java类,或者通过delegateExpression属性指定的委托类,实现了ActivityBehavior接口, 在其excute()方法中控制流程流程离开当前服务任务,沿着指定的外出顺序流继续流转。
public class Demo implements ActivityBehavior {
@Override
public void excute(DelegateExcution excetion){
//改变服务任务的外出顺序流
DelegateHelper.leaveDelagate(excetion, "xxFlow")
}
}
# 在服务任务中使用流程引擎服务接口
某些场景,我们需要在服务任务调用RuntimeService启动一个新流程实例。可以用以下两种方式。
@Component("handleWarMessage")
@Slf4j
public class HandleWarMessageTask implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) throws Exception {
//Camunda 写法
RuntimeService runtimeService = delegateExecution.getProcessEngine().getRuntimeService();
//Activit, Flowable写法
RuntimeService runtimeService = Context.getProcessEngineConfiguration().getRuntimeService();
}
}
@Component("handleWarMessage")
@Slf4j
public class HandleWarMessageTask implements JavaDelegate {
@Autowired
private RuntimeService runtimeService;
@Override
public void execute(DelegateExecution delegateExecution) throws Exception {
runtimeService.startProcessInstanceByMessage("myKey");
}
}
← 用户任务