xiaobaoqiu Blog

Think More, Code Less

Activiti自动流转任务

1.自动流转任务

用户任务是审核流程中最重要的节点, 在流程设计中通常会遇到需要自动流转的需求, 比如请假半天的自动通过.

2.实现

下面是我能想到的几种实现自动流转任务方式.

2.1 ServiceTask

Activiti的设计者已经考虑到我们这个需求,因此在引入了 ServiceTask 这中类型的任务.参考 Activiti 的文档: https://www.activiti.org/userguide/index.html#bpmnJavaServiceTask ServiceTask的目的是调用我们自定义的一个Java类:

1
A Java service task is used to invoke an external Java class.

ServiceTask 的使用方式也有几种:

1. 自定义类实现 JavaDelegate 或者 ActivityBehavior 接口;
2. 设计流程的时候, 显示的告诉 Activiti 引擎需要调用的 Bean;
3. 调用一个方法表达式;
4. 调用一个求值表达式;

下面审核一个示例的自定义ServiceTask调研逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.springframework.stereotype.Service;

/**
 * 自动完成的任务(ServiceTask)
 *
 * @author xiaobaoqiu  Date: 16-12-23 Time: 下午3:46
 */
@Service
public class AutoCompleteTaskService implements JavaDelegate {

    @Override
    public void execute(DelegateExecution execution) throws Exception {

    }
}

回到我们的需求上, 要实现我们需要的自动流转任务, 我们可以使用 ServiceTask, 以上面定义的 AutoCompleteTaskService 为例子:

1
2
3
4
5
6
7
8
# 方式1
<serviceTask id="javaService"
             name="My Java Service Task"
             activiti:class="org.xxx.AutoCompleteTaskService" />

# 方式2
<bean id="delegateExpressionBean" class="org.xxx.AutoCompleteTaskService" />
<serviceTask id="serviceTask" activiti:delegateExpression="${delegateExpressionBean}" />

但是这种实现方式的一个致命的问题在于:流程设计的时候你需要知道你要调用的Java逻辑的类路径或者Bean的名称.

为什么说是致命的呢,因为这个的实现方式就没办法将流程设计交付给开发人员以外的其他人员了(他们不可能知道类路径或者bean名称这种信息).

下面我使用普通的 UserTask 来实现我们的需求.

2.2 主动触发UserTask,

我们将自动流转任务也设计成UserTask, 由业务自己主动触发.

比如请假半天的自动通过的例子, 业务可以在提交请假的时候判断, 让这个任务自动完成.

这种实现的问题在于: 业务逻辑实现起来太麻烦, 很容易出Bug(比如自动通过失败,可能会导致提交这个操作失败).

2.3 异步触发UserTask

在上一个方法的基础上, 我们可以将自动生效的逻辑放到异步任务里面,可以避免将原始业务逻辑复杂化.

但是我们需要筛选出哪些 UserTask 可以自动完成,因此我的方案就是给这些任务制定特定的任务类型.关于任务类型, 可以参考我前面的博文: http://xiaobaoqiu.github.io/blog/2016/12/29/activitiren-wu-zeng-jia-shu-xing/

有了任务类型之后, 我们就可以将哪些任务需要自动流转配置起来.

这个方案的问题在于(绝大部分情况下不是问题): 这里实现的自动生效的不是实时的(即使我们的异步任务足够频繁).

2.4 对比选择

下面是几种实现方式的对比:

成本 ServiceTask 主动触发UserTask 异步触发UserTask
设计成本 需要知道具体的执行类或者Bean
触发成本 需要业务主动触发, 逻辑复杂
配置成本 需要配置:任务类型 - 是否自动完成任务

倾向于使用 异步触发UserTask 这个方案, 成本和问题都比较小.