Activiti子流程学习

Activiti提供两种子流程实现:

1、嵌入子流程
子流程元素 内嵌在主流程元素之内,只能在该流程中使用该子流程,外部是无法访问到的。这种子流程一般作为局部通用逻辑处理,或者因为特定业务需要,使得比较复杂的单个主流程设计清晰直观;
2、调用子流程
首先实现一个流程,在另一个流程中可以调用该流程,通常可以定义一些通用的流程作为这种调用子流程,供其他多个流程定义复用。这种子流程使用 元素来进行调用,间接地嵌入到主流程中,用起来比较方便。
下面通过实例来看下两者的实现:
一、嵌入子流程
1、流程图
以下是流程图的xml表示,可以看到主流程中有一段由标签包围的部分即时流程图中的
Activiti子流程学习_第1张图片
SubProcess的xml表示:
 

二、调用子流程

1、流程图

                Activiti子流程学习_第2张图片

                                                                        主流程:callProcess

主流程xml表示:

其中使用标签 的属性 calledElement 指明子流程定义,并实现 主流程与子流程之间进行数据交换,<activiti:in/>由主流程传入子流程,<activiti:out/>由子流程传给主流程
       

子流程:callledProcess

子流程xml表示,可以看到子流程就是一个正常的独立流程,流程id为calledProcess:


2、应用实例
首先,启动流程代码如下,在发起时给主流程加入全局变量,方便子流程获取,并且在最后记录审批日志,最终我们会看到整个业务流程的日志都是以唯一流程标识划分的:
/***
     *启动流程并记录日志
     *@param businessKey 流程唯一标识
     *@param businessType 业务类型
     *@param businessId 业务id
     * */
    public void start(Long businessKey, Integer businessType, Long businessId, Operator operator) {
        //主流程变量
        Map approveParam = new HashMap<>();
        approveParam.put("businessKey", businessKey);
        approveParam.put("businessType", businessType);
        approveParam.put("businessId", businessId);

        // 启动流程
        runtimeService.startProcessInstanceByKey("callProcess", businessKey.toString(),
            approveParam);

        // 记录日志
        approveRecordService.saveApproveRecord(businessKey, businessType, businessId, "-1",
            FlowNode.Startevent.getCode(), operator.getOperatorId(), ApproveOperation.START.getCode(), "启动流程");
    }
执行流程代码如下:
 /**
     * 审核
     * @param businessKey 流程唯一标识
     * */
    public void approve(Long businessKey){

        //审核变量
        Map approveParam = new HashMap<>();
        approveParam.put("approve", "pass");
        //获取当前任务
        Task currentTask = taskService.createTaskQuery().processInstanceBusinessKey(businessKey.toString()).singleResult();

        Map variables = currentTask.getProcessVariables();
        // 级联结束本节点发起的会签任务
        String parentTaskId = currentTask.getParentTaskId();
        if (parentTaskId != null) {
            List tasks = taskService.createTaskQuery().taskId(parentTaskId).taskDescription("JOINT_PROCESS").list();
            for (Task task : tasks) {
                taskService.setVariablesLocal(task.getId(), null);
                taskService.complete(task.getId(), null);
            }
        }
        //完成当前任务
        taskService.setVariablesLocal(currentTask.getId(), approveParam);
        taskService.complete(currentTask.getId(), approveParam);

        // 记录日志
        approveRecordService.saveApproveRecord(businessKey, (Integer)variables.get("businessType"),
            (Long)variables.get("businessId"), "-1",
            FlowNode.Startevent.getCode(), 888L,
            ApproveOperation.START.getCode(), "启动流程");
    }
如主流程所示,我们发起流程后,执行beforecall,完成后将进入调用子流程Call Activiti模块中,这时子流程会自动跳过空开始结点,生成subTask用户任务的执行 实例和任务,在ACT_RU_EXECUTION和ACT_RU_TASK表中各产生一条新的记录。

但是生成的执行实例缺少唯一业务标识businessKey,这个需要通过监听器实现。
如子流程xml中所示,我们给subTask和subTask2都配置了任务监听器  
 
来,上监听器代码~~~~~~~~~
@Service
public class SubProcessTestListener implements TaskListener {

    private static final long serialVersionUID = 1L;

    @Autowired
    private RuntimeService runtimeService;

    @Transactional
    public void notify(DelegateTask delegateTask){
        System.err.println("1.子流程任务创建======delegateTask{}:" + delegateTask.getId());
        //获取子流程变量
        DelegateExecution execution =  delegateTask.getExecution();
        Long businessId = (Long)execution.getVariable("businessId");
        Integer businessType = (Integer)execution.getVariable("businessType");
        Long businessKey = (Long)execution.getVariable("businessKey");
        System.err.println(
            "2.获取子流程参数======businessId:" + businessId + ";businessType:" + businessType
                + ";businessKey:" + businessKey);

        //子流程实例set业务单号和主流程保持一致
        runtimeService.updateBusinessKey(delegateTask.getProcessInstanceId(), businessKey.toString());
    }
}
这里可以看到主流程xml中,主流程的变量子流程都可以接到,我们利用这些变量中businessKey业务标识,在监听器中填充子流程subTask实例的BUSINESS_KEY_字段,使得子流程和主流程保持业务标识一致,我们流程就可以继续跑下去了。

     
       
       
       
     

 

配置监听器后,调用子流程时,生成实例set了业务标识
Activiti子流程学习_第3张图片
调用子流程执行结束,同时,子流程实例完成,工作流将重新回到主流程:
Activiti子流程学习_第4张图片
正常执行主流程,直到结束,整个业务流程如下:
Activiti子流程学习_第5张图片

你可能感兴趣的:(Activiti子流程学习)