Activiti第三篇【连接、排他网关、指定任务处理人、组任务】

流程变量与网关实践
本文介绍了如何利用流程变量在不同任务间进行条件判断及任务分配,并探讨了排他网关与并行网关的应用场景。

连线

上面我们已将学过了流程变量了,可以在【任务服务、运行时服务、流程开始、完成某个任务时设置流程变量】,而我们的连接就是流程变量的实际应用了….

定义流程图

我们并不是所有的流程都是按一条的路径来走的,我们有的时候会根据条件来走不同的路。当然了,最终该流程是会一步步走完….

例子:

重要的信息交由老板来处理,不重要的信息交由经理来处理

这里写图片描述

表达式的结果必须是布尔型

  • #{variable==’value’}
  • ${variable==value}

测试

我在任务完成时设置流程变量为不重要,那么跳到下一个流程时就是经理来进行处理

这里写图片描述

当我设置为重要的时候,那么就是交由老板来处理

这里写图片描述

排他网关

上面我们使用连线的时候用了两个条件 : 要么条件是“重要”,要么条件是“不重要”….如果有另一种情况呢???就是用户把条件输入错了,写成“不知道重不重要”,那么我们的流程怎么走???岂不是奔溃了???

因此,我们要有一条默认的路来走,就是当该变量不符合任何的条件时,我们也有一条默认的路

这里写图片描述

值得注意的是:如果是在Eclipse中使用插件的BPMN流程图,如果使用了排他网关,那么在Idea下是解析不了的

解决:

我们只要重新定义BPMN流程图的排他网关就行了,idea中的Activiti插件是不用制定默认流程的,只要我们不设置条件,那就是默认的连接线

测试


public class ExclusiveGetWay {
    private ProcessEngine processEngine = ProcessEngines
            .getDefaultProcessEngine();

    // 部署流程定义,资源来在bpmn格式
    @Test
    public void deployProcessDefi() {
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment().name("排他网关流程")
                .addClasspathResource("ExclusiveGateway.bpmn")
                .deploy();

        System.out.println("部署名称:" + deploy.getName());
        System.out.println("部署id:" + deploy.getId());
    }

    // 执行流程,开始跑流程
    @Test
    public void startProcess() {
        String processDefiKey = "bankBill";// bpmn 的 process id属性
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey(processDefiKey);

        System.out.println("流程执行对象的id:" + pi.getId());// Execution 对象
        System.out.println("流程实例的id:" + pi.getProcessInstanceId());// ProcessInstance
                                                                    // 对象
        System.out.println("流程定义的id:" + pi.getProcessDefinitionId());// 默认执行的是最新版本的流程定义
    }

    // 查询正在运行任务
    @Test
    public void queryTask() {
        // 取得任务服务
        TaskService taskService = processEngine.getTaskService();
        // 创建一个任务查询对象
        TaskQuery taskQuery = taskService.createTaskQuery();
        // 办理人的任务列表
        List<Task> list = taskQuery.list();
        // 遍历任务列表
        if (list != null && list.size() > 0) {
            for (Task task : list) {
                System.out.println("任务的办理人:" + task.getAssignee());
                System.out.println("任务的id:" + task.getId());
                System.out.println("任务的名称:" + task.getName());
            }
        }

    }

    // 完成任务
    @Test
    public void compileTask() {
        String taskId = "2404";
        Map<String,Object> params=new HashMap<String, Object>();
        params.put("visitor", 6);
        // taskId:任务id
        processEngine.getTaskService().complete(taskId, params);
//      processEngine.getTaskService().complete(taskId);
        System.out.println("当前任务执行完毕");
    }

}

我们指定的值并不是VIP也不是后台,那么就会自动去普通窗口中处理

这里写图片描述


并行网关

这里写图片描述

等待活动

这里写图片描述

用户任务

使用流程变量指定处理人

我们在快速入门的例子中,是在定义流程图中硬性指定处理人,其实这么干是不够灵活的,我们学了流程变量之后,我们是可以灵活地指定处理人的….

这里写图片描述


    @Test
    public void deployProcessDefi() {
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment().name("用户任务指定流程")
                .addClasspathResource("AppayBill.bpmn")
                .deploy();

        System.out.println("部署名称:" + deploy.getName());
        System.out.println("部署id:" + deploy.getId());
    }

    // 执行流程,开始跑流程
    @Test
    public void startProcess() {
        String processDefiKey = "appayBill";// bpmn 的 process id属性
        Map<String,Object> params=new HashMap<String, Object>();
        params.put("userID", "王某某");
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey(processDefiKey, params);

        System.out.println("流程执行对象的id:" + pi.getId());// Execution 对象
        System.out.println("流程实例的id:" + pi.getProcessInstanceId());// ProcessInstance
        // 对象
        System.out.println("流程定义的id:" + pi.getProcessDefinitionId());// 默认执行的是最新版本的流程定义
    }

    // 查询正在运行任务
    @Test
    public void queryTask() {
        String assignee="王某某";//指定任务处理人
        // 取得任务服务
        TaskService taskService = processEngine.getTaskService();
        // 创建一个任务查询对象
        TaskQuery taskQuery = taskService.createTaskQuery();
        // 办理人的任务列表
        List<Task> list = taskQuery
                .taskAssignee(assignee)
                .list();
        // 遍历任务列表
        if (list != null && list.size() > 0) {
            for (Task task : list) {
                System.out.println("任务的办理人:" + task.getAssignee());
                System.out.println("任务的id:" + task.getId());
                System.out.println("任务的名称:" + task.getName());
            }
        }

    }

这里写图片描述

使用类指定

这里写图片描述

组任务

直接指定办理人

这里写图片描述

使用流程变量

这里写图片描述

使用类

这里写图片描述

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
### 排他网关 (BPMN Exclusive Gateway) 的概念与使用方法 #### 什么是排他网关排他网关是一种用于控制业务流程分支的关键件,在 BPMN(Business Process Model and Notation)标准中被广泛采用。它通过评估多个条件来决定流程的走向,确保每次只有一条路径被执行[^1]。 - **图标表示**:排他网关通常用一个带 “X” 图标的菱形图形表示。“X” 表示异或逻辑(XOR),意味着在多个可能的方向中仅选择其中一个方向继续执行。 - **功能特点**: - 执行到达该网关时,所有出口顺序流会按其定义的顺序逐一计算条件表达式。 - 条件为 `true` 的第一条顺序流会被选中作为后续执行路径[^2]。 - 如果没有任何条件满足,则会抛出异常;如果有多个条件同时为真,默认会选择 XML 中最先定义的那个条件对应的路径。 #### 如何配置排他网关? 以下是使用 Flowable 或 Activiti 等支持 BPMN 的框架实现排他网关的具体方式: ##### 配置文件示例 下面是一个简单的 BPMN 文件片段展示如何定义排他网关及其条件: ```xml <process id="exclusiveGatewayProcess" name="Exclusive Gateway Example"> <!-- 起始节点 --> <startEvent id="startEvent"/> <!-- 排他网关 --> <exclusiveGateway id="decisionPoint" name="Decision Point"/> <!-- 用户任务 A 和 B --> <userTask id="taskA" name="Approve Small Amount"/> <userTask id="taskB" name="Manager Approval"/> <userTask id="taskC" name="Director Approval"/> <!-- 序列流 --> <sequenceFlow id="flow1" sourceRef="startEvent" targetRef="decisionPoint"/> <sequenceFlow id="flow2" sourceRef="decisionPoint" targetRef="taskA"> <conditionExpression xsi:type="tFormalExpression">${amount <= 10000}</conditionExpression> </sequenceFlow> <sequenceFlow id="flow3" sourceRef="decisionPoint" targetRef="taskB"> <conditionExpression xsi:type="tFormalExpression">${amount > 10000 && amount <= 300000}</conditionExpression> </sequenceFlow> <sequenceFlow id="flow4" sourceRef="decisionPoint" targetRef="taskC"> <conditionExpression xsi:type="tFormalExpression">${amount > 300000}</conditionExpression> </sequenceFlow> </process> ``` 上述代码展示了三个不同的审批路径分别适用于不同额度的资金请求场景。每条序列流都有自己的布尔条件表达式,这些表达式的值决定了哪个用户任务将会被激活。 #### 实现细节说明 - **条件表达式语法**: 在实际开发过程中,可以根据所使用的引擎调整 `${}` 内部的内容形式。比如某些情况下允许 Java EL(Expression Language)、JavaScript 或 Groovy 编写复杂判断逻辑。 - **错误处理策略**: 若未设置任何符合条件的情况发生时,应提前规划好应对措施以防程序崩溃。可以通过捕获特定类型的运行期异常来进行优雅降级操作[^1]。 - **测试建议**: 对于涉及多种可能性合的应用场合来说,务必充分验证各种边界情况下的行为表现是否符合预期目标。 --- ### 示例代码 假设我们正在构建一个财务报销系统,并希望利用排他网关完成自动路由分配至相应负责进行审核批准的过程如下所示: ```java // 设置流程变量以便参与决策过程 Map<String, Object> variables = new HashMap<>(); variables.put("amount", 5000); // 假设当前申请金额为 $5k$ runtimeService.startProcessInstanceByKey("exclusiveGatewayProcess", variables); ``` 此段脚本初始化了一个新的实例并将指定数值传递进去供下游环节参考比较之需。 --- 问题
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值