Skip to content

前面的任务负责人都是写死的单个人,在实际开发中通常的情况是一部分人,或某个角色等。Activiti支持使用UEL表达式分配任务流程的负责人,以及更加灵活的监听器的使用。

修改BPMN文件

修改BPMN文件中的assignee,修改成类似EL表达式的形式,如图所示。

image-20230630112130664

动态传递负责人

先使用刚才新创建的BPMN文件创建新的流程实例,和之前文章所写的创建方式没有区别。

java
public void testDeploy() {
     ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    RepositoryService repositoryService = processEngine.getRepositoryService();
    Deployment deployment = repositoryService.createDeployment()
        .addClasspathResource("bpmn/holiday-uel.bpmn20.xml").name("出差流程-uel").deploy();
    System.out.println("部署id" + deployment.getId());
}

传递map文件,作为动态负责人的参数

java
public void testStartProcess() {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    RuntimeService runtimeService = processEngine.getRuntimeService();
    // 启动实例
    Map<String, Object> map = new HashMap<>();
    map.put("assiqnee0", "张三");
    map.put("assiqnee1", "李四");
    map.put("assiqnee2", "王五");
    map.put("assiqnee3", "赵六");
    ProcessInstance holiday = runtimeService.startProcessInstanceByKey("holiday1", map);
    System.out.println("Id" + holiday.getId());
}

UEL表达式

上述表达式通过map,根据字符串获取,但UEL还能从对象获取数据,使用方式如下:

  1. ${value}:直接使用字符串获取的方式
  2. ${user.name}:调用User对象的get方法
  3. ${userBean.getUserId()}:userBean 是 spring 容器中的一个 bean,表示调用该 bean 的 getUserId()方法。
  4. ${userService.find(emp)} :userService 是 spring 容器的一个 bean,find 是该 bean 的一个方法,emp 是 activiti 流程变量, emp 作为参数传到 ldapService.findManagerForEmployee 方法中。
  5. 表达式支持解析基础类型、 bean、 list、 array 和 map,也可作为条件判断。 如下: ${order.price > 100 && order.price < 250}

监听器分配

idea插件中没有,在Camunda modeler中可以查询,安装及使用步骤如下:

  1. 下载对应的软件Camunda官网下载蓝奏云下载,我这里是在win11系统,以camunda-modeler-5.12.1-win-x64.zip为例
  2. 将下载后的压缩包解压
  3. 在idea中File -> Settings -> Tools -> External Tools里添加外部工具

image-20230630145502356

新建BPMN文件

使用原来的方法新建一个BPMN文件,如图所示

新建BPMN文件

插件的使用

任意一个文件右击→External Tools→Camunda,这个Camunda是你甘冈自己起的插件名称;打开后点击File→new File→随便选一个BPMN文件创建。

在Camunda新建文件

创建后点击右下角XML,将你在IDEA创建的BPMN文件的xml内容复制过来,右侧拉去可以展开工具栏,使用方式如下图所示:

Camunda插件使用方式

设置监听器

image-20230630153150841

监听器代码如下所示:

java
package com.xk857.delegrete;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

public class MyTaskListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        // 判断任务名称是否为"创建申请",且事件触发时机是否为"create"
        if ("创建申请".equals(delegateTask.getName()) && "create".equals(delegateTask.getEventName())) {
            delegateTask.setAssignee("吴老师");
        }
    }
}

观察插件中的代码,和源程序代码中的不同之处,复制并修改处理得到:

xml
<!-- 插件中自动生成 -->
<userTask id="sid-a8e083a1-dd21-419c-89ee-2bbe26c8ad7f" name="创建申请">
    <extensionElements>
        <camunda:taskListener class="com.xk857.delegrete.MyTaskListener" event="create" />
    </extensionElements>
</userTask>

<!-- 稍作修改 -->
<userTask id="sid-a8e083a1-dd21-419c-89ee-2bbe26c8ad7f" name="创建申请">
    <extensionElements>
        <activiti:taskListener class="com.xk857.delegrete.MyTaskListener" event="create" />
    </extensionElements>
</userTask>